bool CTopClauses::RunRules(CClauseNode* pCurNode, ESetOfRulesType setOfRulesType, EDirection direction,
                           bool bCanClone, CClauseRules& ClauseRules)
{
    int count = pCurNode->GetNeighbourNodesCount(direction);
    EDirection rev_direction = (direction == LeftToRight) ? RightToLeft : LeftToRight;
    for (int i = 0; i < count; i++) {
        SClauseRelation& rel = pCurNode->GetNeighbourNode(direction, i);
        if (rel.m_pNode->IsEndNode())
            return false;

        CClauseNode* pNode1 = (direction == LeftToRight) ? pCurNode : rel.m_pNode;
        CClauseNode* pNode2 = (direction == LeftToRight) ? rel.m_pNode : pCurNode;

        for (int i = 0; i <  m_SetsOfRules[(int)setOfRulesType].m_Count; i++) {
            ERuleType rule = m_SetsOfRules[setOfRulesType].m_Rules[i];
            if (rel.ShouldApplyRule(rule)) {
                if (ApplyRule(rule, setOfRulesType, pNode1, pNode2,  bCanClone, ClauseRules))
                    return true;
                else
                    rel.SetChouldNotdApplyRule(rule);
            }
        }

        int rev_count = rel.m_pNode->GetNeighbourNodesCount(rev_direction);
        rel.m_pNode->m_VisitedCount++;
        if (rev_count == rel.m_pNode->m_VisitedCount) {
            rel.m_pNode->m_VisitedCount = 0;
            if (RunRules(rel.m_pNode, setOfRulesType, direction, bCanClone, ClauseRules))
                return true;
        }
    }

    return false;
}
Exemple #2
0
/**************************************************************************
 *
 * CreateFiles 
 *
 * SYNOPSIS
 *		int   CreateFiles (LST_LIST *clist, char *filename)
 *
 * PURPOSE
 *		Follow specified rule and create files.
 *
 * INPUT
 *
 *
 * EFFECTS
 *
 *
 * RETURN VALUE
 *
 *
 * BUGS
 *
 *
 * HISTORY
 *
 *
 * SEE ALSO
 *
*/
int   CreateFiles (ConfigType *cf, char *filename)
{
	LST_LIST	*macrolist;
	LST_LIST	*stacklist;
	StackType	*stack;
	MakeMacro	*macro;
	NameType	*name;
	Statement	*st;
	FILE		*fp = NULL;
	int  		 firstflag;
	int  		 error = FALSE;
	int  		 stacksize = 0;

	if (!filename) {
		filename = MAKEFILE;
	}
	macrolist = GetMakeMacros (filename);
	if (!macrolist) {
		return FALSE;
	}

	stacklist = LST_CreateList (NULL);
	if (!stacklist) {
		SetGlobalErr (ERR_OUT_OF_MEMORY);
		GEprintf ("OOM: couldn't allocate stack list");
		return FALSE;
	}

	if (DebugSwitch) {
		PrintMacros (macrolist);
	}

	st = (Statement*)LST_Head (&cf->Statements);
	while (!LST_EndOfList (st)) {
		switch (st->Command) {
		case CMD_OPEN:
			if (fp) {
				fclose (fp);
			}
			fp = fopen (st->Arg1, "w");
			if (!fp) {
				SetGlobalErr (ERR_GENERIC);
				GEprintf1 ("Couldn't open file '%s' for writing", st->Arg1);
				return FALSE;
			}
			break;
		case CMD_PRINT:
			if (!fp) {
				printf ("ERROR:'_Print' command issued with no file opened\n");
				error = TRUE;
				break;
			}
			PrintEscString (LST_NodeName(st), fp);
			break;
		case CMD_NAMES:
			macro = (MakeMacro*)LST_FindName (macrolist, LST_NodeName(st));
			if (!macro) {
				SetGlobalErr (ERR_GENERIC);
				GEprintf2 ("'%s' macro not found in file '%s'", LST_NodeName(st), filename);
				return FALSE;
			}
			if (!fp) {
				printf ("ERROR:'_Names' command issued with no file opened\n");
				error = TRUE;
				break;
			}
			firstflag = TRUE;
			name      = (NameType*)LST_Head (&macro->Names);
			while (!LST_EndOfList (name)) {
				if (firstflag && st->Arg1) {
					firstflag = FALSE;
					if (!ApplyRule (name, st->Arg1, fp)) {
						error = TRUE;
					}
				} else if (st->Arg2) {
					if (!ApplyRule (name, st->Arg2, fp)) {
						error = TRUE;
					}
				}
				while (!LST_EndOfList (name)) {
					if (name->Macro) {
						stack = (StackType*)LST_CreateNode (sizeof (StackType), NULL);
						if (!stack) {
							SetGlobalErr (ERR_OUT_OF_MEMORY);
							GEprintf ("OOM: couldn't allocate stack entry");
							return FALSE;
						}
						stack->Father = name;
						LST_AddTail (stacklist, stack);
						stacksize++;
						name = (NameType*)LST_Head (&name->Macro->Names);
					} else if (name->Delim) {
						name = (NameType*)LST_Next (name);
						break;
					} else {
						name = (NameType*)LST_Next (name);
						while (stacksize && LST_EndOfList (name)) {
							stack = (StackType*)LST_RemTail (stacklist);
							if (stack) {
								name = (NameType*)LST_Next (stack->Father);
								LST_DeleteNode (stack);
								stacksize--;
							}
						}
					}
				}
			}
			if (st->Arg3) {
				PrintEscString (st->Arg3, fp);
			}
			break;
		case CMD_CLOSE:
			if (fp) {
				fclose (fp);
				fp = NULL;
			}
			break;
		}
		st = (Statement*)LST_Next (st);
	}

	return (error ? FALSE : TRUE);
} /* CreateFiles  */
void CNotificationHelper::CheckAndHandleLastUpdateNotification()
{
	if (m_notifications.size() < 1)
		return;

	time_t atime = mytime(NULL);
	atime -= m_NotificationSensorInterval;
	std::map<uint64_t, std::vector<_tNotification> >::const_iterator itt;

	for (itt = m_notifications.begin(); itt != m_notifications.end(); ++itt)
	{
		std::vector<_tNotification>::const_iterator itt2;
		for (itt2 = itt->second.begin(); itt2 != itt->second.end(); ++itt2)
		{
			if (((atime >= itt2->LastSend) || (itt2->SendAlways) || (!itt2->CustomMessage.empty())) && (itt2->LastUpdate)) //emergency always goes true
			{
				std::vector<std::string> splitresults;
				StringSplit(itt2->Params, ";", splitresults);
				if (splitresults.size() < 3)
					continue;
				std::string ttype = Notification_Type_Desc(NTYPE_LASTUPDATE, 1);
				if (splitresults[0] == ttype)
				{
					std::string recoverymsg;
					bool bRecoveryMessage = false;
					bRecoveryMessage = CustomRecoveryMessage(itt2->ID, recoverymsg, true);
					if ((atime < itt2->LastSend) && (!itt2->SendAlways) && (!bRecoveryMessage))
						continue;
					extern time_t m_StartTime;
					time_t btime = mytime(NULL);
					std::string msg;
					std::string szExtraData;
					std::string custommsg;
					uint64_t Idx = itt->first;
					int SensorTimeOut = atoi(splitresults[2].c_str());  // minutes
					int diff = (int)round(difftime(btime, itt2->LastUpdate));
					bool bStartTime = (difftime(btime, m_StartTime) < SensorTimeOut*60);
					bool bSendNotification = ApplyRule(splitresults[1], (diff == SensorTimeOut*60), (diff < SensorTimeOut*60));
					bool bCustomMessage = false;
					bCustomMessage = CustomRecoveryMessage(itt2->ID, custommsg, false);

					if (bSendNotification && !bStartTime && (!bRecoveryMessage || itt2->SendAlways))
					{
						std::vector<std::vector<std::string> > result;
						result = m_sql.safe_query("SELECT SwitchType FROM DeviceStatus WHERE (ID=%" PRIu64 ")", Idx);
						if (result.size() == 0)
							continue;
						szExtraData = "|Name=" + itt2->DeviceName + "|SwitchType=" + result[0][0] + "|";
						std::string ltype = Notification_Type_Desc(NTYPE_LASTUPDATE, 0);
						std::string label = Notification_Type_Label(NTYPE_LASTUPDATE);
						char szDate[50];
						char szTmp[300];
						struct tm ltime;
						localtime_r(&itt2->LastUpdate,&ltime);
						sprintf(szDate, "%04d-%02d-%02d %02d:%02d:%02d", ltime.tm_year + 1900, ltime.tm_mon + 1, ltime.tm_mday,
							ltime.tm_hour, ltime.tm_min, ltime.tm_sec);
						sprintf(szTmp,"Sensor %s %s: %s [%s %d %s]", itt2->DeviceName.c_str(), ltype.c_str(), szDate,
							splitresults[1].c_str(), SensorTimeOut, label.c_str());
						msg = szTmp;
					}
					else if (!bSendNotification && bRecoveryMessage)
					{
						bSendNotification = true;
						msg = recoverymsg;
						std::string clearstr = "!";
						CustomRecoveryMessage(itt2->ID, clearstr, true);
					}
					else
					{
						bSendNotification = false;
					}
					if (bSendNotification)
					{
						if (bCustomMessage && !bRecoveryMessage)
							msg = ParseCustomMessage(custommsg, itt2->DeviceName, "");
						SendMessageEx(Idx, itt2->DeviceName, itt2->ActiveSystems, msg, msg, szExtraData, itt2->Priority, std::string(""), true);
						if (!bRecoveryMessage)
						{
							TouchNotification(itt2->ID);
							CustomRecoveryMessage(itt2->ID, msg, true);
						}
					}
				}
			}
		}
	}
}
bool CNotificationHelper::CheckAndHandleNotification(
	const uint64_t Idx,
	const std::string &devicename,
	const unsigned char devType,
	const unsigned char subType,
	const _eNotificationTypes ntype,
	const float mvalue)
{
	std::vector<_tNotification> notifications = GetNotifications(Idx);
	if (notifications.size() == 0)
		return false;

	char szTmp[600];

	double intpart;
	std::string pvalue;
	if (modf(mvalue, &intpart) == 0)
		sprintf(szTmp, "%.0f", mvalue);
	else
		sprintf(szTmp, "%.1f", mvalue);
	pvalue = szTmp;

	std::vector<std::vector<std::string> > result;
	result = m_sql.safe_query("SELECT SwitchType FROM DeviceStatus WHERE (ID=%" PRIu64 ")", Idx);
	if (result.size() == 0)
		return false;
	std::string szExtraData = "|Name=" + devicename + "|SwitchType=" + result[0][0] + "|";

	time_t atime = mytime(NULL);

	//check if not sent 12 hours ago, and if applicable
	atime -= m_NotificationSensorInterval;

	std::string msg = "";

	std::string ltype = Notification_Type_Desc(ntype, 0);
	std::string nsign = Notification_Type_Desc(ntype, 1);
	std::string label = Notification_Type_Label(ntype);

	std::vector<_tNotification>::const_iterator itt;
	for (itt = notifications.begin(); itt != notifications.end(); ++itt)
	{
		if (itt->LastUpdate)
			TouchLastUpdate(itt->ID);

		if ((atime >= itt->LastSend) || (itt->SendAlways) || (!itt->CustomMessage.empty())) //emergency always goes true
		{
			std::string recoverymsg;
			bool bRecoveryMessage = false;
			bRecoveryMessage = CustomRecoveryMessage(itt->ID, recoverymsg, true);
			if ((atime < itt->LastSend) && (!itt->SendAlways) && (!bRecoveryMessage))
				continue;
			std::vector<std::string> splitresults;
			StringSplit(itt->Params, ";", splitresults);
			if (splitresults.size() < 3)
				continue; //impossible
			std::string ntype = splitresults[0];
			std::string custommsg;
			float svalue = static_cast<float>(atof(splitresults[2].c_str()));
			bool bSendNotification = false;
			bool bCustomMessage = false;
			bCustomMessage = CustomRecoveryMessage(itt->ID, custommsg, false);

			if (ntype == nsign)
			{
				bSendNotification = ApplyRule(splitresults[1], (mvalue == svalue), (mvalue < svalue));
				if (bSendNotification && (!bRecoveryMessage || itt->SendAlways))
				{
					sprintf(szTmp, "%s %s is %s %s [%s %.1f %s]", devicename.c_str(), ltype.c_str(), pvalue.c_str(), label.c_str(), splitresults[1].c_str(), svalue, label.c_str());
					msg = szTmp;
				}
				else if (!bSendNotification && bRecoveryMessage)
				{
					bSendNotification = true;
					msg = recoverymsg;
					std::string clearstr = "!";
					CustomRecoveryMessage(itt->ID, clearstr, true);
				}
				else
				{
					bSendNotification = false;
				}
			}
			if (bSendNotification)
			{
				if (bCustomMessage && !bRecoveryMessage)
					msg = ParseCustomMessage(custommsg, devicename, pvalue);
				SendMessageEx(Idx, devicename, itt->ActiveSystems, msg, msg, szExtraData, itt->Priority, std::string(""), true);
				if (!bRecoveryMessage)
				{
					TouchNotification(itt->ID);
					CustomRecoveryMessage(itt->ID, msg, true);
				}
			}
		}
	}
	return true;
}
bool CNotificationHelper::CheckAndHandleAmpere123Notification(
	const uint64_t Idx,
	const std::string &devicename,
	const float Ampere1,
	const float Ampere2,
	const float Ampere3)
{
	std::vector<_tNotification> notifications = GetNotifications(Idx);
	if (notifications.size() == 0)
		return false;

	char szTmp[600];

	std::string szExtraData = "|Name=" + devicename + "|Image=current48|";

	time_t atime = mytime(NULL);

	//check if not sent 12 hours ago, and if applicable
	atime -= m_NotificationSensorInterval;

	std::string msg = "";

	std::string notValue;

	std::string signamp1 = Notification_Type_Desc(NTYPE_AMPERE1, 1);
	std::string signamp2 = Notification_Type_Desc(NTYPE_AMPERE2, 1);
	std::string signamp3 = Notification_Type_Desc(NTYPE_AMPERE3, 1);

	std::vector<_tNotification>::const_iterator itt;
	for (itt = notifications.begin(); itt != notifications.end(); ++itt)
	{
		if (itt->LastUpdate)
			TouchLastUpdate(itt->ID);

		if ((atime >= itt->LastSend) || (itt->SendAlways) || (!itt->CustomMessage.empty())) //emergency always goes true
		{
			std::string recoverymsg;
			bool bRecoveryMessage = false;
			bRecoveryMessage = CustomRecoveryMessage(itt->ID, recoverymsg, true);
			if ((atime < itt->LastSend) && (!itt->SendAlways) && (!bRecoveryMessage))
				continue;
			std::vector<std::string> splitresults;
			StringSplit(itt->Params, ";", splitresults);
			if (splitresults.size() < 3)
				continue; //impossible
			std::string ntype = splitresults[0];
			std::string custommsg;
			std::string ltype;
			float svalue = static_cast<float>(atof(splitresults[2].c_str()));
			float ampere;
			bool bSendNotification = false;
			bool bCustomMessage = false;
			bCustomMessage = CustomRecoveryMessage(itt->ID, custommsg, false);

			if (ntype == signamp1)
			{
				ampere = Ampere1;
				ltype = Notification_Type_Desc(NTYPE_AMPERE1, 0);
			}
			else if (ntype == signamp2)
			{
				ampere = Ampere2;
				ltype = Notification_Type_Desc(NTYPE_AMPERE2, 0);
			}
			else if (ntype == signamp3)
			{
				ampere = Ampere3;
				ltype = Notification_Type_Desc(NTYPE_AMPERE3, 0);
			}
			bSendNotification = ApplyRule(splitresults[1], (ampere == svalue), (ampere < svalue));
			if (bSendNotification && (!bRecoveryMessage || itt->SendAlways))
			{
				sprintf(szTmp, "%s %s is %.1f Ampere [%s %.1f Ampere]", devicename.c_str(), ltype.c_str(), ampere, splitresults[1].c_str(), svalue);
				msg = szTmp;
				sprintf(szTmp, "%.1f", ampere);
				notValue = szTmp;
			}
			else if (!bSendNotification && bRecoveryMessage)
			{
				bSendNotification = true;
				msg = recoverymsg;
				std::string clearstr = "!";
				CustomRecoveryMessage(itt->ID, clearstr, true);
			}
			else
			{
				bSendNotification = false;
			}
			if (bSendNotification)
			{
				if (bCustomMessage && !bRecoveryMessage)
					msg = ParseCustomMessage(custommsg, devicename, notValue);
				SendMessageEx(Idx, devicename, itt->ActiveSystems, msg, msg, szExtraData, itt->Priority, std::string(""), true);
				if (!bRecoveryMessage)
				{
					TouchNotification(itt->ID);
					CustomRecoveryMessage(itt->ID, msg, true);
				}
			}
		}
	}
	return true;
}
bool CNotificationHelper::CheckAndHandleTempHumidityNotification(
	const uint64_t Idx,
	const std::string &devicename,
	const float temp,
	const int humidity,
	const bool bHaveTemp,
	const bool bHaveHumidity)
{
	std::vector<_tNotification> notifications = GetNotifications(Idx);
	if (notifications.size() == 0)
		return false;

	char szTmp[600];
	std::string notValue;

	std::string szExtraData = "|Name=" + devicename + "|";

	time_t atime = mytime(NULL);

	//check if not sent 12 hours ago, and if applicable

	atime -= m_NotificationSensorInterval;

	std::string msg = "";

	std::string ltemp = Notification_Type_Label(NTYPE_TEMPERATURE);
	std::string signtemp = Notification_Type_Desc(NTYPE_TEMPERATURE, 1);
	std::string signhum = Notification_Type_Desc(NTYPE_HUMIDITY, 1);

	std::vector<_tNotification>::const_iterator itt;
	for (itt = notifications.begin(); itt != notifications.end(); ++itt)
	{
		if (itt->LastUpdate)
			TouchLastUpdate(itt->ID);

		if ((atime >= itt->LastSend) || (itt->SendAlways) || (!itt->CustomMessage.empty())) //emergency always goes true
		{
			std::string recoverymsg;
			bool bRecoveryMessage = false;
			bRecoveryMessage = CustomRecoveryMessage(itt->ID, recoverymsg, true);
			if ((atime < itt->LastSend) && (!itt->SendAlways) && (!bRecoveryMessage))
				continue;
			std::vector<std::string> splitresults;
			StringSplit(itt->Params, ";", splitresults);
			if (splitresults.size() < 3)
				continue; //impossible
			std::string ntype = splitresults[0];
			std::string custommsg;
			float svalue = static_cast<float>(atof(splitresults[2].c_str()));
			bool bSendNotification = false;
			bool bCustomMessage = false;
			bCustomMessage = CustomRecoveryMessage(itt->ID, custommsg, false);

			if (m_sql.m_tempunit == TEMPUNIT_F)
			{
				//Convert to Celsius
				svalue = (svalue / 1.8f) - 32.0f;
			}
			if ((ntype == signtemp) && (bHaveTemp))
			{
				//temperature
				if (temp > 30.0) szExtraData += "Image=temp-gt-30|";
				else if (temp > 25.0) szExtraData += "Image=temp-25-30|";
				else if (temp > 20.0) szExtraData += "Image=temp-20-25|";
				else if (temp > 15.0) szExtraData += "Image=temp-15-20|";
				else if (temp > 10.0) szExtraData += "Image=temp-10-15|";
				else if (temp > 5.0) szExtraData += "Image=temp-5-10|";
				else szExtraData += "Image=temp48|";
				bSendNotification = ApplyRule(splitresults[1], (temp == svalue), (temp < svalue));
				if (bSendNotification && (!bRecoveryMessage || itt->SendAlways))
				{
					sprintf(szTmp, "%s temperature is %.1f %s [%s %.1f %s]", devicename.c_str(), temp, ltemp.c_str(), splitresults[1].c_str(), svalue, ltemp.c_str());
					msg = szTmp;
					sprintf(szTmp, "%.1f", temp);
					notValue = szTmp;
				}
				else if (!bSendNotification && bRecoveryMessage)
				{
					bSendNotification = true;
					msg = recoverymsg;
					std::string clearstr = "!";
					CustomRecoveryMessage(itt->ID, clearstr, true);
				}
				else
				{
					bSendNotification = false;
				}
			}
			else if ((ntype == signhum) && (bHaveHumidity))
			{
				//humidity
				szExtraData += "Image=moisture48|";
				bSendNotification = ApplyRule(splitresults[1], (humidity == svalue), (humidity < svalue));
				if (bSendNotification && (!bRecoveryMessage || itt->SendAlways))
				{
					sprintf(szTmp, "%s Humidity is %d %% [%s %.0f %%]", devicename.c_str(), humidity, splitresults[1].c_str(), svalue);
					msg = szTmp;
					sprintf(szTmp, "%d", humidity);
					notValue = szTmp;
				}
				else if (!bSendNotification && bRecoveryMessage)
				{
					bSendNotification = true;
					msg = recoverymsg;
					std::string clearstr = "!";
					CustomRecoveryMessage(itt->ID, clearstr, true);
				}
				else
				{
					bSendNotification = false;
				}
			}
			if (bSendNotification)
			{
				if (bCustomMessage && !bRecoveryMessage)
					msg = ParseCustomMessage(custommsg, devicename, notValue);
				SendMessageEx(Idx, devicename, itt->ActiveSystems, msg, msg, szExtraData, itt->Priority, std::string(""), true);
				if (!bRecoveryMessage)
				{
					TouchNotification(itt->ID);
					CustomRecoveryMessage(itt->ID, msg, true);
				}
			}
		}
	}
	return true;
}