Open rdevivo74 opened 3 years ago
@alaxtair I also need to get the rule(s) that triggered, which, according to @jruizgit, is not currently supported. By any chance do you have a workaround?
Hello dcrespol thank you for bringing up my topic as it is still something I have to solve in a short time frame. Unfortunately I did not find a workaround yet but it seems another guy managed to do something interesting for my case: https://github.com/jruizgit/rules/issues/296 This is what I was trying to do at last. If I can manage to pass some kind of argument, hardcoded inside the callback name, I could get that in the callback and know which rule has been triggered. It seems a bit hacky to me but no problem if it works fine.
Thanks @alaxtair I was thinking about embedding the parameter value in the action name itself, sort of like what you pointed out: “actionName|myparamvalue”... So, before I tried parsing this, I attempted to create an action with an extra parameter: changed def actionName(c)
to def actionName(c, param=‘some value’)
. In the body, I tried printing param
, but for some reason it is populated by the engine with an object of type “Promise”. How are you defining your action?
I did not manage to make it work unfortunately. I was trying to do the same thing of https://github.com/jruizgit/rules/issues/296 but did not succeed. I tried to do the same thing you described but I got an error so I did not try anything more. If I cannot manage to fix this issue, I cannot define generic actions as I would like to do.
@alaxtair here's what I have managed to do, but I'm still not happy.
First, I inherited from engine.Host as follows:
from durable import engine
import durable_rules_engine
import json
class MyDurableRulesEngine(engine.Host):
_actions = {}
def post(self, ruleset_name, message):
try:
super().post(ruleset_name, message)
except:
return
def add_action(self, action_name, func):
self._actions[action_name] = func
def get_action(self, action_name):
if action_name in self._actions:
param = action_name.split('|')[1]
return self._actions[action_name](param)
else:
super().get_action(action_name)
def set_rules(self, rules):
print('Setting new rules set')
print(json.dumps(rules))
self.set_rulesets(rules)
Then, assuming the following ruleset:
{
"sensor_status_rules": {
"r_0": {
"all": [
{
"m": {
"$and": [
{
"$eq": {
"event_name": "status_updated"
}
},
{
"$eq": {
"sensor_name": "temperature_reader"
}
},
{
"$gte": {
"event_detail.temperature.value": 75
}
}
]
}
}
],
"run": "emit_rule_triggered|Temperature too high"
}
}
}
...and the following actions:
def preprocess_rule_triggered(message):
print('Preprocessing trigger...')
print(message)
print('Calling emit_rule_triggered...')
return emit_rule_triggered
def emit_rule_triggered(c):
"""the body for the actual call from durable_dules""""
...I did:
for rule_definition in durable_rules["sensor_status_rules"].values():
action_name = rule_definition["run"]
self._my_durable_rules_engine.add_action(action_name, preprocess_rule_triggered)
The problem with the above is that I don't have access to the state or anything durable rules engine is providing as part of its c
parameter.
I will start working on this part again because I will need it in the near future. I already looked into the c parameter using the debugging tool. I will let you know as soon as I have results. Please do the same in case you can solve it.
@alaxtair FYI, I ended up implementing a version of the suggestion made by @ruslanolkhovsky in issue https://github.com/jruizgit/rules/issues/296. Take a look at the recent activity in that issue.
Hey @dcrespol, I also managed to make it work yesterday. Thank you very much for pinging me!
First of all, many thanks to Jesus Ruiz and everyone contributing to this project. I am using this package with Python in an IoT scenario, where it fits perfectly. I started using the basic syntax to define rules, the one where the antecedent, which is defined thorugh a decorator, and the consequent are together.
Then, as I am moving to a more dynamic scenario, I managed to separate the antecedents, which are stored in JSON format in a config file, from the consequents (actions), which are methods in a python module. Before, with the basic syntax, I had an action for each consequent.
In the current scenario that I have in mind, multiple antecedents can lead to the same consequent.
How do I get the name of the rule (antecedent) triggered inside the scope of the consequent? I need to know which rule has been triggered when the predefined action is run. Example:
config.yml
durable_rule.py
Thank you.