Commit 9c0a1d47 authored by Vladislav Rykov's avatar Vladislav Rykov
Browse files

real-time alerts and automation added

parent 7515fd5d
...@@ -78,14 +78,10 @@ def create_function_rt(cur, appkey, devid, nfid, expr, action_type, action): ...@@ -78,14 +78,10 @@ def create_function_rt(cur, appkey, devid, nfid, expr, action_type, action):
BEGIN BEGIN
""".format(appkey, devid, nfid) """.format(appkey, devid, nfid)
#PERFORM pg_notify('nf_channel', '{{"appkey":"{}", "devid":{}, "nfid":"{}", "data": row_to_json(NEW.*) }}'); #PERFORM pg_notify('nf_channel', '{{"appkey":"{}", "devid":{}, "nfid":"{}", "lvalue":"{}", "op":"{}", "rvalue":"{}", "action_type":"{}", "action":"{}", "message":' || row_to_json(NEW) || '}}');
#PERFORM pg_notify('nf_channel', json_build_object('appkey','{}','devid',{},'nfid','{}','data',NEW.data));
query += """ query += """
IF (NEW.data->>'{}')::{} {} {} THEN PERFORM pg_notify('nf_channel', '{{"appkey":"{}", "devid":{}, "nfid":"{}", "lvalue":"{}", "op":"{}", "rvalue":"{}", "action_type":"{}", "action":"{}", "message":' || row_to_json(NEW) || '}}');
PERFORM pg_notify('nf_channel', '{{"appkey":"{}", "devid":{}, "nfid":"{}", "action_type":"{}", "action":"{}", "message":' || row_to_json(NEW) || '}}'); """.format(appkey, devid, nfid, expr[0], expr[1], expr[2], action_type, action)
END IF;
""".format( expr[0], get_type(expr[2]), expr[1], expr[2],
appkey, devid, nfid, action_type, action)
query += """ query += """
RETURN NEW; RETURN NEW;
...@@ -95,7 +91,6 @@ def create_function_rt(cur, appkey, devid, nfid, expr, action_type, action): ...@@ -95,7 +91,6 @@ def create_function_rt(cur, appkey, devid, nfid, expr, action_type, action):
LANGUAGE plpgsql VOLATILE LANGUAGE plpgsql VOLATILE
COST 100; COST 100;
""" """
print(query)
cur.execute(query) cur.execute(query)
......
...@@ -177,5 +177,3 @@ def extract(request): ...@@ -177,5 +177,3 @@ def extract(request):
return ddmin return ddmin
print('mpack insert', mpack_test())
print('raw insert', raw_test())
...@@ -6,6 +6,10 @@ import app.dao.notification.notification as nf ...@@ -6,6 +6,10 @@ import app.dao.notification.notification as nf
import app.dao.pend.pend as pend import app.dao.pend.pend as pend
import app.helpers.mailer as mailer import app.helpers.mailer as mailer
import app.helpers.misc as misc import app.helpers.misc as misc
import app.dao.device.device as dd
import app.helpers.device_data_model as ddm
from binascii import unhexlify
@thread @thread
def listening(): def listening():
...@@ -19,18 +23,24 @@ def listening(): ...@@ -19,18 +23,24 @@ def listening():
ps.listen('nf_channel') ps.listen('nf_channel')
while True: while True:
for e in ps.events(): for e in ps.events():
d = json.loads(e.payload) try:
if d['action_type'] == 'alert': d = json.loads(e.payload)
# send mail dev = dd.get(d['appkey'], d['devid'])[1]
n = nf.get(d['appkey'], d['devid'], d['nfid'])[1] d['message']['data'] = ddm.read_data(unhexlify(d['message']['data'][2:]), dev[3])
print(n) if (d['op'][0] == 'O' and d['lvalue'] in d['message']['data']) or eval(str(d['message']['data'][d['lvalue']]) + d['op'] + d['rvalue']):
mailer.send_mail(app, n, d) if d['action_type'] == 'alert':
elif d['action_type'] == 'automation': # send mail
# enqueue confid n = nf.get(d['appkey'], d['devid'], d['nfid'])[1]
# action format: '<devid>#<confid>#<arg>' mailer.send_mail(app, n, d)
action = d['action'].split('#') elif d['action_type'] == 'automation':
base64_args = misc.pend_base64_encode(action[2], action[1]) # enqueue confid
pend.create(d['appkey'], action[0], base64_args) # action format: '<devid>#<confid>#<arg>'
action = d['action'].split('#')
base64_args = misc.pend_base64_encode(action[2], action[1])
pend.create(d['appkey'], action[0], base64_args)
except Exception as e:
print ('Notification manager thread error:', e)
pass
listening() listening()
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<h3 class="mb-0">New Alert</h3> <h3 class="mb-0">New Alert</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="/application/{{ app[1] }}/new-alert" method="post"> <form action="/application/{{ app[1] }}/new-alert" method="post" id="alertform">
<div class="form-group"> <div class="form-group">
<label>Name:</label><br> <label>Name:</label><br>
<input type="text" maxlength="30" class="form-control" id="alertname" name="alertname" required><br> <input type="text" maxlength="30" class="form-control" id="alertname" name="alertname" required><br>
...@@ -37,28 +37,31 @@ ...@@ -37,28 +37,31 @@
<option value="-">Select variable</option> <option value="-">Select variable</option>
</select> </select>
<br> <br>
<select class='form-control notifelem' name='operation' id='operation' required> <select class='form-control notifelem' name='operation' id='operation' onchange="return onop();" required>
<option default>></option> <option selected="selected">></option>
<option>>=</option> <option>>=</option>
<option><</option> <option><</option>
<option><=</option> <option><=</option>
<option>=</option> <option>==</option>
<option>ON UPDATE</option>
</select> </select>
<br> <br>
<input type='text' class='form-control notifelem' name='avalue' id='avalue' placeholder='Value' title='use n (e.g. 5) for integer notation, n.n (e.g. 5.0) for float, and true or false for boolean' required> <input type='text' class='form-control notifelem' name='avalue' id='avalue' placeholder='Value' title='use n (e.g. 5) for integer notation, n.n (e.g. 5.0) for float, and true or false for boolean' required>
<p> Use n (e.g. 5) for integer notation, n.n (e.g. 5.0) for float, and true or false for boolean. <br> <!--
Keep types consistently for each variable for both, alerts and automations. </p> <p> Use n (e.g. 5) for integer notation, n.n (e.g. 5.0) for float, and true or false for boolean. <br>
Keep types consistently for each variable for both, alerts and automations. </p>
-->
</form>
<br> <br>
<h4> THEN </h4> <h4> THEN </h4>
<h5> Send email to: </h5> <h5> Send email to: </h5>
<input class="form-control" type="email" id="alertemail" name="alertemail" placeholder="Type email..." required> <input class="form-control" type="email" form="alertform" id="alertemail" name="alertemail" placeholder="Type email..." required>
<br><br> <br><br>
<div class="form-group"> <div class="form-group">
<button type="submit" id="submit" class="btn btn-primary">Create Alert</button> <button type="submit" id="submit" form="alertform" class="btn btn-primary">Create Alert</button>
</div> </div>
</form>
</div> </div>
</div> </div>
...@@ -93,5 +96,19 @@ ...@@ -93,5 +96,19 @@
} }
validate_form(); validate_form();
} }
function onop() {
var dev_sel = document.getElementById("operation");
var sel_op = dev_sel.options[dev_sel.selectedIndex].text;
var input = document.getElementById("avalue");
if (sel_op[0] == 'O') {
input.setAttribute("type", "hidden");
input.setAttribute("required", "false");
} else {
input.setAttribute("type", "text");
input.setAttribute("required", "true");
}
}
</script> </script>
{% endblock %} {% endblock %}
...@@ -475,7 +475,7 @@ def application_new_alert(appkey): ...@@ -475,7 +475,7 @@ def application_new_alert(appkey):
if res[0]: if res[0]:
# create new function and trigger # create new function and trigger
t = tr.create_function_rt(appkey, request.form['devid'], nid, [request.form['varname'],request.form['operation'],request.form['avalue']],'alert',request.form['alertemail']) t = tr.create_function_rt(appkey, request.form['devid'], nid, [request.form['varname'],request.form['operation'],request.form['avalue']],'alert',request.form['alertemail'])
tr.create(appkey, request.form['devid'], nid) t = tr.create(appkey, request.form['devid'], nid)
flash('Alert created', 'success') flash('Alert created', 'success')
return redirect(url_for('application_alerts', appkey=appkey)) return redirect(url_for('application_alerts', appkey=appkey))
else: else:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment