Here’s the complete solution covering all three focus areas:
Event Binding Validation:
The core issue is that API-created rules don’t automatically establish event bindings. You must create the subscription explicitly:
// First, create the rule
var ruleConfig = {
name: 'TempAlert_' + equipmentId,
property: 'temperature',
condition: 'greaterThan',
threshold: 85,
alertMessage: 'Temperature exceeded',
enabled: true
};
var ruleName = Things['RulesEngine'].CreateRule(ruleConfig);
// Then bind it to the property via subscription
var equipmentThing = Things[equipmentId];
equipmentThing.AddPropertyChangeSubscription({
propertyName: 'temperature',
eventName: 'DataChange',
source: equipmentId,
sourceProperty: 'temperature'
});
The subscription creates the actual event binding that monitors property changes. Without it, the rule exists but never executes.
Validate bindings after creation:
var subscriptions = equipmentThing.GetPropertySubscriptions();
logger.info('Active subscriptions: ' + JSON.stringify(subscriptions));
Ensure you see your temperature property in the list with an active binding to the Rules Engine.
Rule Activation Status:
Verify the rule is truly active at multiple levels:
- Check configuration status:
var rule = Things['RulesEngine'].GetRule({ruleName: ruleName});
if (!rule.enabled) {
Things['RulesEngine'].EnableRule({ruleName: ruleName});
}
- Verify the Thing property configuration:
var propDef = equipmentThing.GetPropertyDefinition({
propertyName: 'temperature'
});
if (propDef.pushType !== 'ALWAYS') {
logger.warn('Property pushType must be ALWAYS for rules');
}
- Test the rule manually:
Things['RulesEngine'].EvaluateRule({
ruleName: ruleName,
currentValue: 90
});
This forces evaluation and confirms the rule logic works correctly.
API Logging:
Enable comprehensive logging to diagnose rule execution:
- Set Rules Engine logging to DEBUG in log4j.properties:
log4j.logger.com.thingworx.rules=DEBUG
- Add custom logging in your rule action:
var ruleConfig = {
name: 'TempAlert_' + equipmentId,
property: 'temperature',
condition: 'greaterThan',
threshold: 85,
action: function(value) {
logger.warn('RULE TRIGGERED: ' + equipmentId +
' temp=' + value);
Things['AlertService'].SendAlert({
equipment: equipmentId,
value: value,
threshold: 85
});
},
enabled: true
};
-
Monitor the ApplicationLog for rule evaluation entries:
- Look for “Evaluating rule: TempAlert_XXX”
- Check for “Rule condition met” or “Rule condition not met”
- Verify property values being evaluated match expectations
-
Create a diagnostic service to verify rule setup:
function ValidateRule(equipmentId) {
var ruleName = 'TempAlert_' + equipmentId;
var rule = Things['RulesEngine'].GetRule({ruleName: ruleName});
var thing = Things[equipmentId];
var subs = thing.GetPropertySubscriptions();
return {
ruleExists: rule !== undefined,
ruleEnabled: rule ? rule.enabled : false,
hasSubscription: subs.some(s => s.property === 'temperature'),
currentValue: thing.temperature,
threshold: rule ? rule.threshold : null
};
}
Run this diagnostic for each equipment item to identify configuration gaps.
Additional considerations:
- Rules created via API don’t persist across server restarts unless you save them to a persistent Thing or configuration table
- Use Thing Templates for equipment that needs identical rules - create the subscription in the template rather than via API
- Implement rule health monitoring that periodically validates all API-created rules are still active and bound correctly
The key difference between UI-created and API-created rules is that the UI automatically handles subscription creation and property binding, while the API requires explicit configuration of each component.