Commit 683cda7b authored by Vladislav Rykov's avatar Vladislav Rykov
Browse files

automation fully implemented

parent 9c76541d
...@@ -2,6 +2,7 @@ from app import app ...@@ -2,6 +2,7 @@ from app import app
from binascii import hexlify from binascii import hexlify
import os import os
import psycopg2 import psycopg2
import binascii
def rand_str(length): def rand_str(length):
if length % 2 == 0: if length % 2 == 0:
...@@ -104,3 +105,17 @@ def paging(cur_pg, ent_cnt, max_ent, max_pg): ...@@ -104,3 +105,17 @@ def paging(cur_pg, ent_cnt, max_ent, max_pg):
pr = [cur_pg-ps, cur_pg+ps+1] pr = [cur_pg-ps, cur_pg+ps+1]
return [pp, pr, np] return [pp, pr, np]
def pend_base64_encode(arg, confid):
argslen = len(arg) + 1
args = bytearray(argslen + 2)
args[0] = int(confid)
args[1] = argslen
bstr = bytes(arg.encode('utf-8'))
i = 0
while i < argslen - 1:
args[2+i] = bstr[i]
i += 1
return binascii.b2a_base64(args).decode('utf-8')
...@@ -17,8 +17,7 @@ ...@@ -17,8 +17,7 @@
<table class="table"> <table class="table">
<thead> <thead>
<th> Name </th> <th> Name </th>
<th> Condition </th> <th> Automation Statement </th>
<th> Action </th>
<th> </th> <th> </th>
</thead> </thead>
<tbody> <tbody>
...@@ -26,7 +25,6 @@ ...@@ -26,7 +25,6 @@
<tr> <tr>
<th> {{ a[3] }} </th> <th> {{ a[3] }} </th>
<th> {{ a[4] }} </th> <th> {{ a[4] }} </th>
<th> {{ a[6] }} </th>
<th> <a href="/automation-rm?id={{ a[0] }}&devid={{ a[2] }}"> <span class="glyphicon glyphicon-remove"</span> </a> </th> <th> <a href="/automation-rm?id={{ a[0] }}&devid={{ a[2] }}"> <span class="glyphicon glyphicon-remove"</span> </a> </th>
</tr> </tr>
{% endfor %} {% endfor %}
......
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
function onvar() { function onvar() {
if (!document.getElementById("operation")) { if (!document.getElementById("operation")) {
$("#alertform").append("<select class='form-control notifelem' name='operation' id='operation' required><option default>></option><option>>=</option><option><</option><option><=</option><option>=</option></select>"); $("#alertform").append("<select class='form-control notifelem' name='operation' id='operation' required><option default>></option><option>>=</option><option><</option><option><=</option><option>=</option></select>");
$("#alertform").append("<input type='numeric' class='form-control notifelem' name='avalue' id='avalue' placeholder='Value' required>"); $("#alertform").append("<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>");
} else { } else {
var var_sel = document.getElementById("varname"); var var_sel = document.getElementById("varname");
var sel_var = var_sel.options[var_sel.selectedIndex].value; var sel_var = var_sel.options[var_sel.selectedIndex].value;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
<div class="col-md-6"> <div class="col-md-6">
<h2> Add New Automation </h2> <h2> Add New Automation </h2>
<br><br> <br><br>
<form id="automationform" action="alert" method="post"> <form id="automationform" action="automation" method="post">
<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="automationname" name="automationname" required><br> <input type="text" maxlength="30" class="form-control" id="automationname" name="automationname" required><br>
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
<h5> Set config on </h5> <h5> Set config on </h5>
<div id="THEN"> <div id="THEN">
<select class="form-control" id="adevid" name="adevid" onchange="onadev()" required> <select form="automationform" class="form-control" id="adevid" name="adevid" onchange="onadev()" required>
<option default value="-">Select Device</option> <option default value="-">Select Device</option>
{% for d in devs %} {% for d in devs %}
<option value="{{ d[1] }}">{{ d[0] }}</option> <option value="{{ d[1] }}">{{ d[0] }}</option>
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
function onvar() { function onvar() {
if (!document.getElementById("operation")) { if (!document.getElementById("operation")) {
$("#automationform").append("<select class='form-control notifelem' name='operation' id='operation' required><option default>></option><option>>=</option><option><</option><option><=</option><option>=</option></select>"); $("#automationform").append("<select class='form-control notifelem' name='operation' id='operation' required><option default>></option><option>>=</option><option><</option><option><=</option><option>=</option></select>");
$("#automationform").append("<input type='numeric' class='form-control notifelem' name='avalue' id='avalue' placeholder='Value' required>"); $("#automationform").append("<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>");
} else { } else {
var var_sel = document.getElementById("varname"); var var_sel = document.getElementById("varname");
var sel_var = var_sel.options[var_sel.selectedIndex].value; var sel_var = var_sel.options[var_sel.selectedIndex].value;
...@@ -92,8 +92,8 @@ ...@@ -92,8 +92,8 @@
var dev_sel = document.getElementById("adevid"); var dev_sel = document.getElementById("adevid");
var sel_op = dev_sel.options[dev_sel.selectedIndex].value; var sel_op = dev_sel.options[dev_sel.selectedIndex].value;
if (sel_op != "-") { if (sel_op != "-") {
$("#THEN").append("<input type='number' size='3' min='0' max='255' class='form-control notifelem' id='confid' name='confid' placeholder='Conf ID' required>"); $("#THEN").append("<input type='number' form='automationform' size='3' min='0' max='255' class='form-control notifelem' id='confid' name='confid' placeholder='Conf ID' required>");
$("#THEN").append("<textarea type='text' maxlength='50' class='form-control notifelem' id='arg' name='arg' rows='2' placeholder='Args' reqiured></textarea>"); $("#THEN").append("<textarea type='text' form='automationform' maxlength='50' class='form-control notifelem' id='arg' name='arg' rows='2' placeholder='Args' reqiured></textarea>");
} else { } else {
$("#confid").remove(); $("#confid").remove();
$("#arg").remove(); $("#arg").remove();
......
...@@ -16,8 +16,8 @@ import app.dao.notification_queue.notification_queue as nq ...@@ -16,8 +16,8 @@ import app.dao.notification_queue.notification_queue as nq
import app.helpers.misc as misc import app.helpers.misc as misc
import app.helpers.mailer as mailer import app.helpers.mailer as mailer
import binascii
import os import os
import binascii
MAX_PG = 5 MAX_PG = 5
...@@ -31,7 +31,6 @@ def index(): ...@@ -31,7 +31,6 @@ def index():
apps = ad.get_list(session['name']) apps = ad.get_list(session['name'])
session.pop('appkey', None) session.pop('appkey', None)
# print('apps: ', apps)
if apps[0]: if apps[0]:
return render_template('public/index.html', apps=apps[1], users_signup=app.config['USERS_SIGNUP']) return render_template('public/index.html', apps=apps[1], users_signup=app.config['USERS_SIGNUP'])
else: else:
...@@ -185,8 +184,6 @@ def new_dev(): ...@@ -185,8 +184,6 @@ def new_dev():
if 'name' in session: if 'name' in session:
dev_list = dd.get_list(session['appkey']) dev_list = dd.get_list(session['appkey'])
#print('dev list : ', dev_list)
if not dev_list[0]: if not dev_list[0]:
return render_template('public/add-dev.html', feedback=dev_list[1]) return render_template('public/add-dev.html', feedback=dev_list[1])
else: else:
...@@ -254,19 +251,7 @@ def dev_conf(): ...@@ -254,19 +251,7 @@ def dev_conf():
else: else:
return render_template('public/dev-conf.html', devname=session['devname']) return render_template('public/dev-conf.html', devname=session['devname'])
else: else:
argslen = len(request.form['arg']) + 1 base64_args = pend_base64_encode(request.form['arg'], request.form['confid'])
args = bytearray(argslen + 2)
args[0] = int(request.form['confid'])
args[1] = argslen
bstr = bytes(request.form['arg'].encode('utf-8'))
i = 0
while i < argslen - 1:
args[2+i] = bstr[i]
i += 1
base64_args = binascii.b2a_base64(args).decode('utf-8')
pend.create(session['appkey'], session['devid'], base64_args) pend.create(session['appkey'], session['devid'], base64_args)
return redirect(url_for('dev', id=session['devid'])) return redirect(url_for('dev', id=session['devid']))
...@@ -387,7 +372,6 @@ def dashboard(): ...@@ -387,7 +372,6 @@ def dashboard():
if 'users_filter' in session: if 'users_filter' in session:
users = ud.get_range_name(session['users_filter'], [MAX_PG_ENTRIES_USERS, (cur_pg-1)*MAX_PG_ENTRIES_USERS]) users = ud.get_range_name(session['users_filter'], [MAX_PG_ENTRIES_USERS, (cur_pg-1)*MAX_PG_ENTRIES_USERS])
print(users)
rd = misc.paging(cur_pg, len(users[1]), MAX_PG_ENTRIES_USERS, MAX_PG) rd = misc.paging(cur_pg, len(users[1]), MAX_PG_ENTRIES_USERS, MAX_PG)
else: else:
users = ud.get_range([MAX_PG_ENTRIES_USERS, (cur_pg-1)*MAX_PG_ENTRIES_USERS]) users = ud.get_range([MAX_PG_ENTRIES_USERS, (cur_pg-1)*MAX_PG_ENTRIES_USERS])
...@@ -412,7 +396,6 @@ def user(): ...@@ -412,7 +396,6 @@ def user():
apps = ad.get_list(name) apps = ad.get_list(name)
session.pop('appkey', None) session.pop('appkey', None)
# print('apps: ', apps)
if apps[0]: if apps[0]:
return render_template('admin/user.html', apps=apps[1], username=name) return render_template('admin/user.html', apps=apps[1], username=name)
else: else:
...@@ -431,27 +414,22 @@ def user_delete(): ...@@ -431,27 +414,22 @@ def user_delete():
if app_list[0]: if app_list[0]:
for app in app_list[1]: for app in app_list[1]:
devs = dd.get_list(app[1]) devs = dd.get_list(app[1])
print('devs: {}'.format(devs))
for dev in devs[1]: for dev in devs[1]:
res = data.delete_table(app[1], dev[1]) res = data.delete_table(app[1], dev[1])
print ('data del {}'.format(res))
if not res[0]: if not res[0]:
break break
if res[0]: if res[0]:
res = dd.delete_table(app[1]) res = dd.delete_table(app[1])
print ('devices del {}'.format(res))
if res[0]: if res[0]:
res = ad.delete(app[1]) res = ad.delete(app[1])
print ('app del {}'.format(res))
if not res[0]: if not res[0]:
break break
if res[0]: if res[0]:
res = ud.delete(user[1][0]) res = ud.delete(user[1][0])
print ('user del {}'.format(res))
if not res[0]: if not res[0]:
flash('Error: {}'.format(res[1]), 'danger') flash('Error: {}'.format(res[1]), 'danger')
...@@ -544,20 +522,21 @@ def alert(): ...@@ -544,20 +522,21 @@ def alert():
# create new notification # create new notification
nid = misc.rand_str(app.config['NID_LENGTH']).decode('utf-8') nid = misc.rand_str(app.config['NID_LENGTH']).decode('utf-8')
dev = dd.get(session['appkey'], request.form['devid']) dev = dd.get(session['appkey'], request.form['devid'])
desc = dev[1][0]+'.'+request.form['varname']+' '+request.form['operation']+' '+request.form['avalue'] try:
desc = dev[1][0]+'.'+request.form['varname']+' '+request.form['operation']+' '+request.form['avalue']
res = nfs.create(nid, session['appkey'], request.form['devid'], request.form['alertname'], desc, 'alert', request.form['alertemail']) res = nfs.create(nid, session['appkey'], request.form['devid'], request.form['alertname'], desc, 'alert', request.form['alertemail'])
if res[0]: if res[0]:
# create new function and trigger # create new function and trigger
r = tr.create_function(session['appkey'], request.form['devid'], nid, [request.form['varname'],request.form['operation'],request.form['avalue']]) tr.create_function(session['appkey'], request.form['devid'], nid, [request.form['varname'],request.form['operation'],request.form['avalue']])
print ('tr.create_function', r) tr.create(session['appkey'], request.form['devid'], nid)
r = tr.create(session['appkey'], request.form['devid'], nid) return redirect(url_for('alerts'))
print('tr.create', r) else:
return redirect(url_for('alerts')) flash('Error creating new alert: {}'.format(res[1]), 'danger')
else: return redirect(url_for('alerts'))
flash('Error creating new notification: {}'.format(res[1]), 'danger') except Exception as e:
return redirect(url_for('alerts')) flash('Error creating new alert: {}. Make sure you have filled all form fields.'.format(e), 'danger')
return redirect(url_for('new_alert'))
else: else:
return redirect(url_for('index')) return redirect(url_for('index'))
else: else:
...@@ -566,7 +545,7 @@ def alert(): ...@@ -566,7 +545,7 @@ def alert():
@app.route('/alert-rm') @app.route('/alert-rm')
def alarm_rm(): def alarm_rm():
if 'name' in session: if 'name' in session:
nq.delete_list(session['appkey']) nq.delete(session['appkey'], request.args.get('devid'), request.args.get('id'))
tr.delete(session['appkey'], request.args.get('devid'), request.args.get('id')) tr.delete(session['appkey'], request.args.get('devid'), request.args.get('id'))
tr.delete_function(session['appkey'], request.args.get('devid'), request.args.get('id')) tr.delete_function(session['appkey'], request.args.get('devid'), request.args.get('id'))
res = nfs.delete(session['appkey'], request.args.get('devid'), request.args.get('id')) res = nfs.delete(session['appkey'], request.args.get('devid'), request.args.get('id'))
...@@ -589,7 +568,28 @@ def automation(): ...@@ -589,7 +568,28 @@ def automation():
return render_template('public/automation.html', auto_list=auto[1]) return render_template('public/automation.html', auto_list=auto[1])
elif request.method == 'POST': elif request.method == 'POST':
# new automation # new automation
return redirect(url_for('autmation')) nid = misc.rand_str(app.config['NID_LENGTH']).decode('utf-8')
dev = dd.get(session['appkey'], request.form['devid'])
adev = dd.get(session['appkey'], request.form['adevid'])
try:
desc = 'IF '+dev[1][0]+'.'+request.form['varname']+' '+request.form['operation']+' '+request.form['avalue']+' THEN '+adev[1][0]+'.confID_'+request.form['confid']+' = '+request.form['arg']
# action format: '<devid>#<confid>#<arg>'
action = request.form['adevid']+'#'+request.form['confid']+'#'+request.form['arg']
res = nfs.create(nid, session['appkey'], request.form['devid'], request.form['automationname'], desc, 'automation', action)
if res[0]:
# create new function and trigger
tr.create_function(session['appkey'], request.form['devid'], nid, [request.form['varname'],request.form['operation'],request.form['avalue']])
tr.create(session['appkey'], request.form['devid'], nid)
return redirect(url_for('automation'))
else:
flash('Error creating new alert: {}'.format(res[1]), 'danger')
return redirect(url_for('automation'))
return redirect(url_for('autmation'))
except Exception as e:
flash('Error creating new automation: {}. Make sure you have filled all form fields correctly.'.format(e), 'danger')
return redirect(url_for('automation'))
else: else:
return redirect(url_for('index')) return redirect(url_for('index'))
...@@ -608,17 +608,16 @@ def pend_delete_all_ack(): ...@@ -608,17 +608,16 @@ def pend_delete_all_ack():
def fire_notifications(app): def fire_notifications(app):
fnfs = nq.get_all() fnfs = nq.get_all()
print ('nq.get_all ', fnfs)
if fnfs[0]: if fnfs[0]:
for fnf in fnfs[1]: for fnf in fnfs[1]:
nf = nfs.get(fnf[1], fnf[2], fnf[0]) nf = nfs.get(fnf[1], fnf[2], fnf[0])
print('nfs.get ', nf)
if nf[1][5] == 'alert': if nf[1][5] == 'alert':
# send mail # send mail
mailer.send_mail(app, nf[1], fnf) mailer.send_mail(app, nf[1], fnf)
nq.delete(fnf[1], fnf[2], fnf[0])
print('send alert mail')
elif nf[1][5] == 'automation': elif nf[1][5] == 'automation':
# enqueue conf id # enqueue confid
print('automation') # action format: '<devid>#<confid>#<arg>'
action = nf[1][6].split('#')
base64_args = misc.pend_base64_encode(action[2], action[1])
pend.create(nf[1][1], action[0], base64_args)
nq.delete(fnf[1], fnf[2], fnf[0])
...@@ -73,6 +73,34 @@ CREATE TABLE public.users ( ...@@ -73,6 +73,34 @@ CREATE TABLE public.users (
); );
-- ALTER TABLE public.notifications OWNER TO pi;
--
-- Name: users; Type: TABLE; Schema: public; Owner: pi
--
CREATE TABLE public.notifications (
id character varying(10) NOT NULL,
app_key character varying(30) NOT NULL,
dev_id numeric(3) NOT NULL,
name character varying(50) NOT NULL,
description character varying(300),
action_type character varying(20) NOT NULL,
action character varying (200) NOT NULL
);
-- ALTER TABLE public.notifications_queue OWNER TO pi;
--
-- Name: users; Type: TABLE; Schema: public; Owner: pi
--
CREATE TABLE public.notifications_queue (
nf_id character varying(10) NOT NULL,
app_key character varying(30) NOT NULL,
dev_id numeric(3) NOT NULL,
fired_on timestamp(6) NOT NULL
);
-- ALTER TABLE public.users OWNER TO pi; -- ALTER TABLE public.users OWNER TO pi;
-- --
...@@ -105,6 +133,30 @@ ALTER TABLE ONLY public.users ...@@ -105,6 +133,30 @@ ALTER TABLE ONLY public.users
ALTER TABLE ONLY public.applications ALTER TABLE ONLY public.applications
ADD CONSTRAINT applications_username_fkey FOREIGN KEY (username) REFERENCES public.users(name); ADD CONSTRAINT applications_username_fkey FOREIGN KEY (username) REFERENCES public.users(name);
--
-- Name: notifications notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: pi
--
ALTER TABLE ONLY public.notifications
ADD CONSTRAINT notifications_pkey PRIMARY KEY (id, app_key, dev_id);
--
-- Name: notifications notifications_app_key_fkey; Type: FK CONSTRAINT; Schema: public; Owner: pi
--
ALTER TABLE ONLY public.notifications
ADD CONSTRAINT notifications_app_key_fkey FOREIGN KEY (app_key) REFERENCES public.applications(app_key);
--
-- Name: notifications notifications_queue_pkey; Type: CONSTRAINT; Schema: public; Owner: pi
--
ALTER TABLE ONLY public.notifications_queue
ADD CONSTRAINT notifications_queue_pkey PRIMARY KEY (nf_id, app_key, dev_id);
--
-- Name: notifications_queue notifications_queue_app_key_fkey; Type: FK CONSTRAINT; Schema: public; Owner: pi
--
ALTER TABLE ONLY public.notifications_queue
ADD CONSTRAINT notifications_queue_app_key_fkey FOREIGN KEY (app_key, nf_id, dev_id) REFERENCES public.notifications(app_key, id, dev_id);
INSERT INTO public.users VALUES('admin', '$2b$12$chdF4ji1maIRLd4ms4s4yugFv.2BTvOAwiaWi6iRlTJzlGKjpTcA.', 'admin') INSERT INTO public.users VALUES('admin', '$2b$12$chdF4ji1maIRLd4ms4s4yugFv.2BTvOAwiaWi6iRlTJzlGKjpTcA.', 'admin')
-- --
......
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