diff --git a/germany/app.py b/germany/app.py
new file mode 100644
index 0000000..ab0af26
--- /dev/null
+++ b/germany/app.py
@@ -0,0 +1,1093 @@
+from flask import Flask, Response, request
+from os import path, system, remove
+import datetime
+from time import sleep, time
+import matplotlib.pyplot as plt
+import numpy as np
+import cv2
+from subprocess import Popen, PIPE
+import json
+import requests
+
+
+import telebot
+tbToken='5536375305:AAHGkcHW-_PqhNDP8Zl27X7Q0_TD6vksQ9U'
+bot = telebot.TeleBot(tbToken)
+homeToken='5563613923:AAFGYdokQYJfTTQYhJftGZy3KtMDSZg5p6Q';
+homebot = telebot.TeleBot(homeToken)
+
+alertsToken='6307305357:AAErNusrWuzZDb0KgSol5JGc7gqpFi7mqxk';
+alertsbot = telebot.TeleBot(alertsToken)
+vbat_low = 2.9
+def tg_alert(msg):
+ #ids = '420641258,245058979'
+ ids = '245058979'
+ uids = ids.split(",")
+ for uid in uids:
+ alertsbot.send_message(uid, msg)
+ return
+
+ap=path.abspath(__file__)
+script_dir = path.dirname(ap)
+log_file_tmpl = "%s/log/sb_%s_%s.log"
+show_html_file = "%s/show.html" % script_dir
+show_chart_file = "%s/templates/img.html" % script_dir
+sha_1a_html_file= "%s/templates/sba_1accel_img.html" % script_dir
+
+app = Flask(__name__)
+
+buf_file = 'data.buf'
+
+chart_size = 12
+
+home_dir = "/home/shurik/SmartBed/src"
+def make_1accel_graph(devid, lcnt):
+ datadir = "log"
+ log = "%s/%s/sbadat.%s" % (home_dir, datadir, devid)
+ img_name = "%s/tmp/img_sbadat_%s.png" % (home_dir, devid)
+
+ databuf = Popen(["tail", "-n%i" % lcnt, log], stdout=PIPE, encoding='utf-8').communicate()[0]
+ lines = [line.rstrip() for line in databuf.split("\n")]
+
+ x=[];y=[];z=[];stm=[];vbat=[];deltas=[]
+ def parseLine(l):
+ td=l.split("\t")
+ if np.shape(td)[0]<3 :
+ return
+ dat_tmp=td[2].split("\\n")
+ dat = dat_tmp[np.size(dat_tmp)-1].replace("'","").split(";")
+ stm.append(td[0].split(" ")[1].split(".")[0])
+ vbat.append(dat_tmp[np.size(dat_tmp)-2].split(" ")[-1].replace("\\r",''))
+ for m in dat:
+ # print("m=[%s]" % m)
+ ms=m.split(",")
+ x.append(int(ms[1]))
+ y.append(int(ms[2]))
+ z.append(int(ms[3]))
+ return
+
+ for l in lines:
+ parseLine(l)
+ #print(np.shape(x))
+ deltas=[max(x)-min(x),max(y)-min(y),max(z)-min(z)]
+
+ image_shape = (720, 1280, 3) # (1080, 1920, 3)
+ imH, imW = [720, 1280] # [1080, 1920]
+ image = np.zeros(image_shape, dtype=np.uint8)
+
+ c0 = (255, 0, 0)
+ c1 = (0, 255, 0)
+ c2 = (0, 0, 255)
+
+ thickness = 2
+ gpoints = np.shape(x)[0]
+ rd=10 # смещение графика от верхнего/нижнего края
+ gdelta = 20 # смещение графика от левого/правого края
+ wStep = (imW - gdelta*2) / gpoints #/2
+
+ maxHVal = 16000
+ halfH = imH/2
+ xavg=np.mean(x); yavg=np.mean(y); zavg=np.mean(z)
+ x=(np.array(x)-xavg)/maxHVal*imH + halfH
+ y=(np.array(y)-yavg)/maxHVal*imH + halfH
+ z=(np.array(z)-zavg)/maxHVal*imH + halfH
+
+
+ xg=[];yg=[];zg=[]
+ for j in range(gpoints):
+ Wval = int(gdelta + wStep*j)
+ xg.append([Wval, int(x[j])])
+ yg.append([Wval, int(y[j])])
+ zg.append([Wval, int(z[j])])
+
+ xg = np.array(xg, np.int32).reshape((-1, 1, 2))
+ yg = np.array(yg, np.int32).reshape((-1, 1, 2))
+ zg = np.array(zg, np.int32).reshape((-1, 1, 2))
+ isClosed = False
+ image = cv2.polylines(image, [xg], isClosed, c0, thickness)
+ image = cv2.polylines(image, [yg], isClosed, c1, thickness)
+ image = cv2.polylines(image, [zg], isClosed, c2, thickness)
+ #cv2.putText(image, "%s / %sV" % (stm[0], vbat[0]), (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 2)
+ cv2.putText(image, "%sV" % (vbat[-1]), (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 2)
+ cv2.putText(image, "dlt %i" % (deltas[0]), (imW-200, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, c0, 2)
+ cv2.putText(image, "dlt %i" % (deltas[1]), (imW-200, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, c1, 2)
+ cv2.putText(image, "dlt %i" % (deltas[2]), (imW-200, 150), cv2.FONT_HERSHEY_SIMPLEX, 1, c2, 2)
+ cv2.putText(image, "sum %i" % (sum(deltas)), (imW-200, 200), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
+
+ for i in range(lcnt-1):
+ vline = [[int(imW/lcnt*(i+1)), 20], [int(imW/lcnt*(i+1)), imH-20]]
+ vline = np.array(vline, np.int32).reshape((-1, 1, 2))
+ cv2.polylines(image, [vline], isClosed, (200, 200, 200), thickness)
+ cv2.putText(image, "%s" % (stm[i+1]), (int(imW/lcnt*(i+1))+5, imH-40), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
+
+
+ cv2.imwrite(img_name, image)
+ return(img_name)
+
+
+ax_mid_lim = 512
+ax_max_lim = 1024
+def make_4axels_plot(dev, id, axl, ln, axel_cnt, steps, pdCnt):
+ datadir = "log"
+ logid = id
+ log = "%s/%s/sb_%s_%s.log" % (home_dir, datadir, dev, logid)
+ img_name = "%s/tmp/img_%s_%s_%s.png" % (home_dir, dev, logid, axl.replace(',', '-'))
+ axels4graph=[int(an)-1 for an in axl.split(',')]
+ maxaxels4graphcnt = 4
+ axels4graphcnt = min(maxaxels4graphcnt, len(axels4graph))
+ scale = 5 # увеличение сигнала на графике
+ log_lines = int(ln)
+ dd = 1 # data_delta - пропускаем первое значение - таймер
+ log_recs_delta = 1.5 # интервал между записями в логе
+ ax = [[[],[],[]] for n in range(axel_cnt)]
+ times = []
+ cc=0
+ databuf = Popen(["tail", "-n%i" % log_lines, log], stdout=PIPE, encoding='utf-8').communicate()[0]
+ lines = [line.rstrip() for line in databuf.split("\n")]
+ for l in lines:
+ if len(l) <=1 :
+ break
+ times.append(l.split("\t")[0])
+ args = l.split("\t")[1].split(",")
+ for sn in range(steps):
+ dlt = sn * 3 * axel_cnt
+ for i in range(axel_cnt):
+ # dd - data_delta
+ #ax[i][0].append(int(args[dlt + i*3+0+dd]) if int(args[dlt + i*3+0+dd]) < ax_mid_lim else int(args[dlt + i*3+0+dd]) - ax_max_lim)
+ #ax[i][1].append(int(args[dlt + i*3+1+dd]) if int(args[dlt + i*3+1+dd]) < ax_mid_lim else int(args[dlt + i*3+1+dd]) - ax_max_lim)
+ #ax[i][2].append(int(args[dlt + i*3+2+dd])-280 if int(args[dlt + i*3+2+dd]) < ax_mid_lim else int(args[dlt + i*3+2+dd]) - ax_max_lim)
+ # NEW for mpu6050 data in float format
+ ax[i][0].append(int(float(args[dlt + i*3+0+dd])*100));
+ ax[i][1].append(int(float(args[dlt + i*3+1+dd])*100));
+ ax[i][2].append(int(float(args[dlt + i*3+2+dd])*100-1000));
+ cc+=1
+ ax_shape = np.shape(ax)
+ axMax = [[0, 0, 0] for n in range(axel_cnt)]
+ axMin = [[0, 0, 0] for n in range(axel_cnt)]
+ deltaMax = 0
+ for ai in range(axel_cnt):
+ for i in range(3):
+ axMax[ai][i] = max(ax[ai][i])
+ axMin[ai][i] = min(ax[ai][i])
+ if axMax[ai][i] == axMin[ai][i]:
+ axMax[ai][i] += 1
+ deltaMax = (axMax[ai][i] - axMin[ai][i]) if (axMax[ai][i] - axMin[ai][i]) > deltaMax else deltaMax
+ a1,a2,glen = np.shape(ax)
+ imH, imW = [1080, 1920]
+ image_shape = (imH, imW, 3)
+ image = np.zeros(image_shape, dtype=np.uint8)
+ gpoints = ax_shape[2]
+ gphalf = gpoints / 2
+ gdelta = 20 # смещение графика от левого/правого края
+ hStep = (imH - 10) / (4 / 2) - 10
+ wStep = (imW - gdelta*2) / gpoints /2
+ hpix = 2 # int(65000 / hStep) # вес одного вертикального пикселя
+ isClosed = False
+ c0 = (255, 0, 0)
+ c1 = (0, 255, 0)
+ c2 = (0, 0, 255)
+ thickness = 2
+ vline = [[imW/2, 20], [imW/2, imH-20]]
+ vline = np.array(vline, np.int32).reshape((-1, 1, 2))
+ hline = [[20, imH/2], [imW-20, imH/2]]
+ hline = np.array(hline, np.int32).reshape((-1, 1, 2))
+ radius = 20
+ color = [(0, 0, 225), (225, 225, 255)]
+ aiH = [1, 1, 0, 0]
+ aiW = [0, 1, 0, 1]
+ cnt = 0
+ fc = 0
+ pdcnt = 0
+ ret_val = True
+ printflag=True
+ gstep = 5
+ dsize = 20 # размер анализируемого на движение участка
+ msize = 3 # meter size / интервал измерения от текущей точки назад
+ body = ["nogi", "ruki", "telo"]
+
+
+ for istep in range(1):
+ image *= 0
+ image -=1
+ acnt = 0 # int(cnt / input_frm_rates * (steps / log_recs_delta) )
+ pdcnt = int(acnt/10)
+ dstart = acnt-dsize if acnt> dsize else 0
+ mstart = acnt-msize if acnt> msize else 0
+ gstart = 0 # int((acnt-gphalf) if (acnt>gphalf) else 0)
+ gstop = glen #int((acnt+gphalf) if (acnt<(glen-gphalf)) else glen)
+ chartlen = int(gstop - gstart)
+ ldelta = int(gdelta) #int(gdelta if (gstart>0) else gdelta + (gphalf - acnt)*wStep)
+ ax4ch = [[[],[],[]] for n in range(axels4graphcnt)]
+ j=0
+ for i in range(gstart, gstop):
+ Wval = [int(ldelta + wStep*j) , int(imW/2+ldelta + wStep*j)]
+ for ai in range(axels4graphcnt):
+ ax4ch[ai][0].append([Wval[aiW[ai]], int((ax[axels4graph[ai]][0][i]*scale+80)/hpix + 10 + aiH[ai]*hStep+150)])
+ ax4ch[ai][1].append([Wval[aiW[ai]], int((ax[axels4graph[ai]][1][i]*scale+80)/hpix + 10 + aiH[ai]*hStep+150)])
+ ax4ch[ai][2].append([Wval[aiW[ai]], int((ax[axels4graph[ai]][2][i]*scale+80)/hpix + 10 + aiH[ai]*hStep+150)])
+ j += 1
+ for i in range(axels4graphcnt):
+ ax4ch[i][0] = np.array(ax4ch[i][0], np.int32).reshape((-1, 1, 2))
+ ax4ch[i][1] = np.array(ax4ch[i][1], np.int32).reshape((-1, 1, 2))
+ ax4ch[i][2] = np.array(ax4ch[i][2], np.int32).reshape((-1, 1, 2))
+ for i in range(axels4graphcnt):
+ image = cv2.polylines(image, [ax4ch[i][0]], isClosed, c0, thickness)
+ image = cv2.polylines(image, [ax4ch[i][1]], isClosed, c1, thickness)
+ image = cv2.polylines(image, [ax4ch[i][2]], isClosed, c2, thickness)
+ image = cv2.polylines(image, [vline], isClosed, (200, 200, 200), thickness)
+ image = cv2.polylines(image, [hline], isClosed, (200, 200, 200), thickness)
+ for i in range(axels4graphcnt):
+ labH = int(50+imH*aiH[i]/2)
+ labW = int(20+imW*aiW[i]/2)
+ cv2.putText(image, "axel %i" % (axels4graph[i]+1), (labW, labH), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
+ cv2.imwrite(img_name,image)
+ return(img_name)
+
+
+def make_plot(fname, id):
+# https://pyprog.pro/mpl/mpl_main_components.html
+ with open(fname, 'r') as f:
+ lines = [line.rstrip() for line in f]
+ axel_cnt = 4
+ steps = 10 # количество измерений в одной строке
+ pd_delta = steps * axel_cnt * 3
+ if len(lines)<=0:
+ fig, chrts = plt.subplots(axel_cnt+1, 3, figsize=(20,25))
+ img_name = "%s_chart.png" % fname
+ plt.savefig(img_name)
+ fig.clear()
+ plt.close( fig )
+ return(img_name)
+
+ ax = [ [[],[],[]],
+ [[],[],[]],
+ [[],[],[]],
+ [[],[],[]]
+ ]
+
+ ax1 = []
+ ax2 = []
+ ax3 = []
+ pd = []
+ cnt = 0
+ acnt= 0
+ for l in lines:
+ b = l.split("\t")
+ args = b[1].split(",")
+ for sn in range(steps):
+ sdif = sn * 3
+ for i in range(axel_cnt):
+ # ad +1 - skip timemark
+ i0 = int(args[sdif+i*3+1])
+ i1 = int(args[sdif+i*3+2])
+ i2 = int(args[sdif+i*3+3])
+ ax[i][0].append([acnt, i0 if i0 < ax_mid_lim else i0 - ax_max_lim])
+ ax[i][1].append([acnt, i1 if i1 < ax_mid_lim else i1 - ax_max_lim])
+ ax[i][2].append([acnt, i2 if i2 < ax_mid_lim else i2 - ax_max_lim])
+ acnt += 1
+ pd_val = (5 - int(args[pd_delta]) - int(args[pd_delta+1]) - int(args[pd_delta+2]) - int(args[pd_delta+3]) - int(args[pd_delta+4]))
+ pd.append([cnt, pd_val])
+ cnt += 1
+ for i in range(axel_cnt):
+ ax[i][0] = [list(n) for n in zip(*ax[i][0])]
+ ax[i][1] = [list(n) for n in zip(*ax[i][1])]
+ ax[i][2] = [list(n) for n in zip(*ax[i][2])]
+ #fig = plt.figure(figsize=(20,10))
+ #print(ax[1][0])
+ pd = [list(n) for n in zip(*pd)]
+ fig, chrts = plt.subplots(axel_cnt+1, 3, figsize=(20,25))
+ for i in range(axel_cnt):
+ chrts[i, 0].set_title("кровать %s / акселерометр %i ось 1" % (id, i), size = 10)
+ chrts[i, 1].set_title("кровать %s / акселерометр %i ось 2" % (id, i), size = 10)
+ chrts[i, 2].set_title("кровать %s / акселерометр %i ось 3" % (id, i), size = 10)
+ chrts[i, 0].plot(ax[i][0][0], ax[i][0][1],color = 'green', linewidth = 2)
+ chrts[i, 1].plot(ax[i][1][0], ax[i][1][1],color = 'red', linewidth = 2)
+ chrts[i, 2].plot(ax[i][2][0], ax[i][2][1],color = 'blue', linewidth = 2)
+ chrts[axel_cnt, 1].set_title("кровать %s / датчик давления" % id, size = 10)
+ chrts[axel_cnt, 1].plot(pd[0], pd[1],color = 'magenta', linewidth = 2)
+ img_name = "%s_chart.png" % fname
+ plt.savefig(img_name)
+ fig.clear()
+ plt.close( fig )
+ return(img_name)
+
+
+@app.route('/')
+def root_dir():
+ return('Hello!')
+
+@app.route('/SmartBed')
+def sb_get_data():
+ id = request.args.get('id')
+ if not id:
+ id = '0'
+ dev = request.args.get('dev')
+ if not dev:
+ dev = '0'
+ data = request.args.get('data')
+ if not data:
+ return('no data\n')
+ else:
+ fname = "%s.%s_%s" % (buf_file, dev, id)
+ with open(fname, 'w') as f:
+ f.write(data)
+ log_file = log_file_tmpl % (script_dir, dev, id)
+ ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
+ with open(log_file, 'a') as f:
+ f.write("%s\t%s\n" % (ts, data))
+ return 'OK!\n'
+
+@app.route('/SBShow')
+def sb_show_data():
+ llimit = request.args.get('limit')
+ if not llimit:
+ llimit = '10'
+ id = request.args.get('id')
+ if not id:
+ id = '0'
+ dev = request.args.get('dev')
+ if not dev:
+ dev = '0'
+ fname = "%s.%s_%s" % (buf_file, dev, id)
+ log_file = log_file_tmpl % (script_dir, dev, id)
+ data = ''
+ try:
+ if llimit :
+ new_log = "%s---" % log_file
+ system("tail -n%s %s > %s" % (llimit, log_file, new_log))
+ log_file = new_log
+ with open(log_file, 'r') as f:
+ data = f.read()
+ except Exception as e:
+ data = "data log is empty\n"
+ return Response(data, mimetype='text/plain')
+
+@app.route('/SBAxStat')
+def sb_axels_stat():
+ t = request.args.get('axel_cnt')
+ if not t:
+ axel_cnt = 39
+ else:
+ axel_cnt = int(t)
+ t = request.args.get('steps')
+ if not t:
+ steps = 10
+ else:
+ steps = int(t)
+ t = request.args.get('pdCnt')
+ if not t:
+ pdCnt = 20
+ else:
+ pdCnt = int(t)
+ pd_delta = steps * axel_cnt * 3 + 1 # пропускаем первое значение - таймер
+
+ id = request.args.get('id')
+ llimit = request.args.get('l')
+ if not id:
+ id = '0'
+ if not llimit:
+ llimit = '1'
+ if not dev:
+ dev = '0'
+ log_file = log_file_tmpl % (script_dir, dev, id)
+ lines=[]
+ try:
+ new_log = "%s----" % log_file
+ system("tail -n%s %s > %s" % (llimit, log_file, new_log))
+ log_file = new_log
+ with open(log_file, 'r') as f:
+ lines = [line.rstrip() for line in f]
+ except Exception as e:
+ data = "data log is empty\n"
+
+
+ # read data
+ #with open(log_file, 'r') as f:
+ # lines = [line.rstrip() for line in f]
+ ax = [[0 for i in range(3)] for n in range(axel_cnt)]
+ # prepare data
+ cnt = 0
+ for l in lines:
+ args = l.split("\t")[1].split(",")
+ for sn in range(steps):
+ dlt = sn * 3 * axel_cnt
+ for i in range(axel_cnt):
+ # если уберут первое значение (метку таймера), то прибавку надо начинать не с 1, а с 0
+ ax[i][0]+= 1 if int("0"+args[dlt + i*3+1]) == 0 else 0
+ ax[i][1]+= 1 if int("0"+args[dlt + i*3+2]) == 0 else 0
+ ax[i][2]+= 1 if int("0"+args[dlt + i*3+3]) == 0 else 0
+ cnt+=1
+
+ # делаем таблицу
+ buf = "
\n"
+ for i in range(axel_cnt):
+ buf+="| %i " % (i+1)
+ buf+="[%i, %i, %i] | " % (ax[i][0],ax[i][1],ax[i][2])
+ if i>0 and ((i+1)%3)==0:
+ buf+="
\n"
+ if i<(axel_cnt-1):
+ buf+=""
+ if (axel_cnt%3) > 0:
+ buf+="
\n"
+ buf+="
\n"
+ data="количество нулевых значений (из %i измерений, %i строк)\n" % (cnt*10, cnt)
+ data+=buf
+ data+=""
+
+ return Response(data, mimetype='text/html')
+
+@app.route('/SBShow_html')
+def sb_show_html():
+ with open(show_html_file, 'r') as f:
+ data = f.read()
+ return Response(data, mimetype='text/html')
+
+@app.route('/SBA_1a_html')
+def sba_1accel_html():
+ id = request.args.get('id')
+ if not id:
+ id = '0'
+ with open(sha_1a_html_file, 'r') as f:
+ data = f.read()
+ return Response(data.replace("<%id%>", id), mimetype='text/html')
+
+@app.route('/SBA_1a_chart')
+def sba_1accel_chart():
+ lines = 10
+ id = request.args.get('id')
+ if not id:
+ id = '0'
+ img_file = make_1accel_graph(id, lines)
+ data = ''
+ with open(img_file, 'rb') as f:
+ data = f.read()
+ return Response(data, mimetype='image/png')
+
+
+@app.route('/SBShow_chart_r')
+def sb_show_img_refreshl():
+ with open(show_chart_file, 'r') as f:
+ data = f.read()
+ return Response(data, mimetype='text/html')
+
+@app.route('/SBShow_chart')
+def sb_show_chart():
+ id = request.args.get('id')
+ if not id:
+ id = '0'
+ if not dev:
+ dev = '0'
+ log_file = log_file_tmpl % (script_dir, dev, id)
+ tmp_file = "%s/tmp/sb_%s_%s" % (script_dir, dev, id)
+ cmd = "tail -n%i %s > %s" % (chart_size, log_file, tmp_file)
+ system(cmd)
+ img_file = make_plot(tmp_file, dev, id)
+ data = ''
+ with open(img_file, 'rb') as f:
+ data = f.read()
+ return Response(data, mimetype='image/png')
+
+@app.route('/SBShow_4axchart')
+def sb_show_4axels_chart():
+ t = request.args.get('axel_cnt')
+ if not t:
+ axel_cnt = 39
+ else:
+ axel_cnt = int(t)
+ t = request.args.get('steps')
+ if not t:
+ steps = 10
+ else:
+ steps = int(t)
+ t = request.args.get('pdCnt')
+ if not t:
+ pdCnt = 20
+ else:
+ pdCnt = int(t)
+
+ id = request.args.get('id')
+ if not id:
+ id = '0'
+ dev = request.args.get('dev')
+ if not dev:
+ dev = '0'
+ axl = request.args.get('ax')
+ if not axl:
+ axl = '1'
+ ln = request.args.get('l')
+ if not ln:
+ ln = '1'
+
+
+ img_file = make_4axels_plot(dev, id, axl, ln, axel_cnt, steps, pdCnt)
+ data = ''
+ with open(img_file, 'rb') as f:
+ data = f.read()
+ return Response(data, mimetype='image/png')
+
+
+btnsNames = {
+'1': 'Гигиена',
+'2': 'Массаж',
+'3': 'Кормление',
+'4': 'Лекарства',
+'5': 'Переворот',
+'6': 'Прогулка'
+}
+iv_snapshots_tmpl="./iv_snapshots/%s.jpg"
+vid_data_file_tmpl = "./ivideon/data/vid/%s.%i"
+vid_counter_video = "./ivideon/data/counter.mp4"
+vid_duration = 10
+iv_cam_id = "100-0KW14UQLJmUe0KvQesKQku:0"
+def get_atok(pid):
+ tok_file="./ivideon/data/%s.tok" % pid
+ with open(tok_file, 'r') as f:
+ data = f.read()
+ jdat = json.loads(data)
+ return(jdat['access_token'])
+
+
+def send_ivid_foto(ids, pult_id, id):
+ uids = ids.split(",")
+ gif_ids={}
+ for uid in uids:
+ repl=bot.send_video(chat_id=uid, video=open(vid_counter_video, 'rb'), supports_streaming=True)
+ gif_ids[uid] = repl.message_id
+ access_token = get_atok(pult_id)
+ foto_cmd = "./iv_get_jpg.sh openapi-alpha-eu01.ivideon.com \"%s\" \"%s\" %s" % (iv_cam_id, access_token, pult_id)
+ with open('foto_cmd.txt', 'w') as f:
+ f.write(foto_cmd)
+ system(foto_cmd)
+ sleep(2)
+ system(foto_cmd)
+ imgfile = iv_snapshots_tmpl % id
+ for uid in uids:
+ bot.delete_message(chat_id=uid,message_id=gif_ids[uid])
+ if(path.getsize(imgfile) < 300):
+ with open(imgfile, 'r') as f:
+ data = f.read()
+ jdat = json.loads(data)
+ msg = "%s / %s" % (jdat['code'], jdat['message'])
+ for uid in uids:
+ bot.send_message(uid, msg)
+ else:
+ #print("IVIDEON IMAGE FILE: %s" % imgfile)
+ ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
+ vid_start_cmd = "curl -X POST \"https://openapi-alpha-eu01.ivideon.com/cameras/%s?op=REC\" -d \"{\\\"duration\\\":%i}\" -H \"Authorization: Bearer %s\"" % (iv_cam_id, vid_duration, access_token)
+ system(vid_start_cmd)
+ vid_time_id = int(time())
+ msg = "%s\n" %ts
+ for uid in uids:
+ repl=bot.send_photo(uid, open(imgfile, 'rb'), ts)
+ msg+="%s/%s " % (uid, repl.message_id)
+ msg=msg.rstrip()+"\n"
+ vid_load_cmd = "./ivideon/puskach \"./ivideon/video_load.sh %s %i %i %s >/dev/null 2>&1\"" % (id, vid_duration, vid_time_id, iv_cam_id)
+ msg+=vid_start_cmd+"\n"+vid_load_cmd+"\n"
+ vid_data_file = vid_data_file_tmpl % (id, vid_time_id)
+ with open(vid_data_file, 'w') as f:
+ f.write(msg)
+ system("mv %s ./tmp/iv.jpg" % imgfile)
+ system(vid_load_cmd)
+ return
+
+
+doorOpsNames = {
+ '1': 'открыта',
+ '2': 'закрыта'
+}
+doorStateToOp = {
+ 'open': '1',
+ 'close': '2'
+}
+
+@app.route('/shelly_door', methods = ['POST', 'GET'])
+def sb_shelly_door():
+ id = request.args.get('id')
+ if not id:
+ id = '1'
+ ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
+ with open("./log//shelly_door.log", "a") as f:
+ f.write("%s: %s: " % (ts, request.method))
+ if request.method == "GET":
+ if(request.query_string):
+ f.write("id=%s, " % id)
+ f.write(str(request.query_string))
+ else:
+ f.write("no request.query_string")
+ f.write("\n")
+ # жёсткие установки для отладки
+ ids = '420641258,245058979'
+ id = 1
+ #------------------------------
+ doorid = request.args.get('door')
+ if not doorid:
+ doorid = '1'
+ state = request.args.get('state')
+ if state:
+ if not (state in doorStateToOp):
+ state = 'close'
+ op = doorStateToOp[state]
+ #op = request.args.get('op')
+ #if not op:
+ # op = '2'
+ if not (op in doorOpsNames):
+ op = '2'
+ pult_id = id
+ temp = request.args.get('temp')
+ lux = request.args.get('lux')
+ msg = "модуль %s. дверь %s. %s. Свет %s lux, темп. %s C" % (id, doorid, doorOpsNames[op], lux, temp)
+ uids = ids.split(",")
+ for uid in uids:
+ bot.send_message(uid, msg)
+ send_ivid_foto(ids, pult_id, id)
+ return 'shelly door %s\n' % state
+ return 'empty hook data\n'
+
+
+dbotcmd="src-c/wraponce -l \"python3 door2tlg.py --did %s --ds %s --dv %s --tgids %s --tgtok %s --t %s --h %s\""
+@app.route('/doorchk')
+def sb_doorchk():
+ doorid = request.args.get('doorid')
+ doorstat = request.args.get('doorstat')
+ vbat = request.args.get('vbat')
+ temp = request.args.get('t')
+ hum = request.args.get('h')
+ if not doorid:
+ return 'ERROR! No door number\n'
+ if not doorstat:
+ return 'ERROR! No door status\n'
+ if not vbat:
+ vbat = "-1"
+ else:
+ if(float(vbat) < vbat_low):
+ tg_alert("DOOR CHECK [%s] VBAT LOW %s" % (doorid, vbat))
+ if not temp:
+ temp = "-1"
+ if not hum:
+ hum = "-1"
+
+ ids = '420641258,245058979'
+ #ids = '245058979'
+ cmd = dbotcmd % (doorid, doorstat, vbat, ids, tbToken, temp, hum) #homeToken)
+ system(cmd)
+
+ #ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
+ #if(int(doorstat)==0):
+ # msg = "Дверь %s. Закрытие. %s\n" % (doorid, ts)
+ #else:
+ # msg = "Дверь %s. Открытие. %s" % (doorid, ts)
+
+ #uid = "245058979"
+ #homebot.send_message(uid, msg)
+ return 'Сообщение отправлено\n'
+
+
+ids_list_tmpl = "./tlg_id_lists/%s.idl"
+@app.route('/btn2tlg')
+def sb_btn2tlg():
+ btn = request.args.get('btn')
+ id = request.args.get('id')
+ if not id:
+ id = '1'
+ if not btn:
+ return 'ERROR! No button number\n'
+ #ids = request.args.get('idlist')
+ #===========================================
+ ids = '420641258,245058979'
+ #ids = ''
+ ids_file = ids_list_tmpl % id
+ if path.exists(ids_file):
+ with open(ids_file, 'r') as f:
+ ids = f.read()
+ ids.rstrip()
+ #===========================================
+ if not ids:
+ return 'ERROR! No IDs list\n'
+ cnt = 0
+ ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
+ if not (btn in btnsNames):
+ btn = '0'
+ if(int(btn)==0):
+ msg = "Пульт %s. Включение\n" % id
+ else:
+ msg = "Пульт %s. Нажата кнопка №%s \"%s\"\n%s\n" % (id, btn,btnsNames[btn], ts)
+ pult_id = id
+
+ uids = ids.split(",")
+ for uid in uids:
+ bot.send_message(uid, msg)
+ cnt += 1
+ if id == '1' and btn == '4':
+ ids = '420641258,245058979'
+ #ids = '245058979'
+ send_ivid_foto(ids, pult_id, id)
+ return 'Отправлено сообщений: %i\n' % cnt
+
+@app.route('/btns')
+def sb_btns():
+ id = request.args.get('id')
+ if not id:
+ id = '0'
+ dev = request.args.get('dev')
+ if not dev:
+ dev = '0'
+ cnt=0
+ rf = []
+ args_shape = []
+ btn_status = ["OFF", "PRESS"]
+ #if(True):
+ log_file = log_file_tmpl % (script_dir, dev, id)
+ buf=""
+ try:
+ with open(log_file, 'r') as f:
+ lines = [line.rstrip() for line in f]
+ except Exception as e:
+ buf="can't open log file"
+ lines=[]
+ for l in lines:
+ if len(l) <=1 :
+ break
+ times = l.split("\t")[0]
+ args = l.split("\t")[1].split(",")
+ if cnt==0:
+ args_shape = np.shape(args)
+ rf = np.zeros(args_shape, dtype=np.uint8)
+
+ chck=False
+ n=0
+ for a in args:
+ if n :
+ i = int(args[n])
+ if rf[n] != i:
+ chck = True
+ rf[n] = i
+ n+=1
+ if chck or cnt==0 :
+ ans = "%s:\t" % times
+ for i in range(n-1):
+ ans += " %s," % btn_status[rf[i+1]]
+ #print(ans)
+ #print(rf)
+ buf += "%s\n" % ans
+ cnt+=1
+ return Response(buf, mimetype='text/plain')
+
+# FOR GET FILES FROM TELEGA BOT
+foto_tbToken = '1917924056:AAFPW0bfl3ZihH9l0luaU0nt6WrRsVMLVT8'
+from pyzbar.pyzbar import decode
+from PIL import Image
+#import requests
+@app.route('/QRScan')
+def scan_qr_code():
+ file_id = request.args.get('file_id')
+ bot_token = request.args.get('token')
+ if not file_id:
+ answ = "no file id"
+ else:
+ if not bot_token:
+ fotobot = telebot.TeleBot(foto_tbToken)
+ else:
+ fotobot = telebot.TeleBot(bot_token)
+ answ = "file id is: %s" % file_id
+ print(file_id)
+ file_path = fotobot.get_file(file_id).file_path
+ print(file_path)
+ file = fotobot.download_file(file_path)
+ af = file_path.split('.')
+ print(af)
+ file_ext = af[1]
+ file_name = "tmp/foto_%s.%s" %(file_id, file_ext)
+ with open(file_name, "wb") as code:
+ code.write(file)
+ answ = decode(Image.open(file_name))[0].data.decode("utf-8")
+ print(answ)
+ remove(file_name)
+ return Response(answ, mimetype='text/plain')
+
+# IVIDEON redirection url
+@app.route('/ivr')
+def ivr():
+ answ = 'OK\n'
+ rez = 1
+ #if not ac:
+ # answ = 'ERR autorization_code\n'
+ # ac = 'no autorization_code'
+ # #rez = 0
+ code = request.args.get('code')
+ if not code:
+ answ = 'ERR code\n'
+ rez = 0
+ if rez == 1:
+ fname = "ivideon_code_new"
+ answ = "%scode\t%s\n" % (answ, code)
+ with open(fname, 'w') as f:
+ f.write("code\t%s\n" % code)
+ #=============================================================
+ #======= request =============================================
+ payload = {
+ 'client_id' : 'knopka',
+ 'client_secret' : '29dc2e257b76be074d772e07f9a8f444',
+ 'grant_type' : 'authorization_code',
+ 'code' : code,
+ 'redirect_uri' : 'https://pilot.papageno.ru/ivr'
+ }
+ url = 'https://api.ivideon.com/auth/oauth/token'
+ response = requests.post(url, data=payload, verify=False)
+ with open(fname, 'a') as f:
+ f.write("\n============================================\n")
+ f.write("text\t%s\n" % response.text)
+ f.write("\n============================================\n")
+ #=============================================================
+ with open(fname, 'r') as f:
+ data = f.read()
+ answ = "%s%s\n" % (answ, data)
+ return Response(answ, mimetype='text/plain')
+
+
+def ivr_OLD():
+ #ac = request.args.get('autorization_code')
+ answ = 'OK\n'
+ rez = 1
+ #if not ac:
+ # answ = 'ERR autorization_code\n'
+ # ac = 'no autorization_code'
+ # #rez = 0
+ code = request.args.get('code')
+ if not code:
+ answ = 'ERR code\n'
+ rez = 0
+ if rez == 1:
+ fname = "ivideon_code"
+ answ = "%scode\t%s\n" % (answ, code)
+ with open(fname, 'w') as f:
+ f.write("code\t%s\n" % code)
+ curl = "curl -X POST -d 'client_id=knopka&client_secret=29dc2e257b76be074d772e07f9a8f444&grant_type=authorization_code&code=%s&redirect_uri=https://pilot.papageno.ru/ivr' 'https://api.ivideon.com/auth/oauth/token'" % code
+ answ = "%s%s\n" % (answ, curl)
+ system("%s >> %s" % (curl, fname))
+
+ with open(fname, 'a') as f:
+ f.write("\n===================== HEADERS ===============\n")
+ if(request.headers):
+ for hname in request.headers.keys():
+ f.write("%s: %s\n" % (hname, request.headers[hname]))
+ f.write("\n============================================\n")
+
+
+ with open(fname, 'r') as f:
+ data = f.read()
+ answ = "%s%s\n" % (answ, data)
+ return Response(answ, mimetype='text/plain')
+
+# GET ENV and POST data
+@app.route('/sbadat', methods = ['POST']) # Smart Bed Acel DATa
+def sbadat():
+ try:
+ if(not request.headers):
+ return('ERR headers\n')
+ if(not request.headers["Title"]):
+ return('ERR Title\n')
+ i = request.headers["Title"].find(",")
+ ap_id = request.headers["Title"][:i]
+ ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
+ rdat = request.data
+ #==================================================================
+ # определение корректности данных и проверка вольтажа датчика
+ print("sbadat: data check")
+ try:
+ str_rdat = "%s" % rdat
+ i = str_rdat.find("Start step")
+ if(i < 0):
+ tg_alert("SBADAT point %s DATA CORRUPT\n%s: %s\n%s" % (ap_id, ts, request.headers["Title"], str_rdat))
+ return "SBA DATA CORRUPT"
+ dat_tmp=str_rdat.split("\\n")
+ vbat = dat_tmp[np.size(dat_tmp)-2].split(" ")[-1].replace("\\r",'')
+ if(float(vbat) < vbat_low):
+ tg_alert("SBADAT point %s VBAT LOW %s" % (ap_id, vbat))
+ #==================================================================
+ except Exception as e:
+ print("SBADAT: data check error")
+ print(e)
+ with open("./log/sbadat.%s" % ap_id, 'a') as f:
+ f.write("%s\t%s\t%s\n" % (ts, request.headers["Title"], rdat))
+ except Exception as e:
+ print(e)
+ return("sba work error")
+ return 'OK!\n'
+
+@app.route('/thermodat', methods = ['POST', 'GET']) # Smart Bed Acel DATa
+def thermodat():
+ try:
+ if(not request.headers):
+ return('ERR headers\n')
+ if(not request.headers["Title"]):
+ return('ERR Title\n')
+ i = request.headers["Title"].find(",")
+ ap_id = request.headers["Title"][:i]
+ ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
+ rdat = request.data
+ #==================================================================
+ # определение корректности данных и проверка вольтажа датчика
+ print("thermodat: data check")
+ with open("./log/thermodat.%s" % ap_id, 'a') as f:
+ f.write("%s\t%s\t%s\n" % (ts, request.headers["Title"], rdat))
+ except Exception as e:
+ print(e)
+ return("thermodat work error")
+ return 'OK!\n'
+
+
+@app.route('/hm')
+def heart_mon():
+ data = request.args.get('data')
+ answ = 'OK'
+ if not data:
+ data = 'data empty'
+ answ = 'ERR'
+ ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
+ with open("./log/heart_mon.stat", 'a') as f:
+ f.write("%s\t%s\n" % (ts, data))
+ p=data.split(",")
+ tm=int(time())
+ if len(p) >=3 :
+ ma=p[2].replace(':','')
+ #cmd="mosquitto_pub -u \"shurik\" -P \"Iehbr2023\" -h 127.0.0.1 -p 1883 -t \"homeassistant/sensor/sugar001/state\" -m '{\"MAC\":\"%s\",\"mmol\":%s,\"temp\":%s,\"time\":%i}'" % (p[2],p[0], p[1],tm)
+ if len(p) >=5 :
+ cmd="mosquitto_pub -u \"shurik\" -P \"Iehbr2023\" -h 127.0.0.1 -p 1883 -t \"sugarcontrol/sensor/sugar/%s/state\" -m '{\"MAC\":\"%s\",\"mmol\":%s,\"temp\":%s,\"time\":%i,\"sensor\":\"%s\"}'" % (p[4],p[2],p[0], p[1],int(p[3])/1000,p[4])
+ #cmd="mosquitto_pub -u \"shurik\" -P \"Iehbr2023\" -h 127.0.0.1 -p 1883 -t \"homeassistant/sensor/sugar/%s/state\" -m '{\"MAC\":\"%s\",\"mmol\":%s,\"temp\":%s,\"time\":%i}'" % (ma,p[2],p[0], p[1],int(p[3])/1000)
+ else :
+ cmd="mosquitto_pub -u \"shurik\" -P \"Iehbr2023\" -h 127.0.0.1 -p 1883 -t \"homeassistant/sensor/sugar/%s/state\" -m '{\"MAC\":\"%s\",\"mmol\":%s,\"temp\":%s,\"time\":%i}'" % (ma,p[2],p[0], p[1],tm)
+ print(cmd)
+ system(cmd)
+ else:
+ print("test data?")
+ return answ
+
+@app.route('/hmShow')
+def nm_show():
+ llimit = 10
+ log_file = "./log/heart_mon.stat"
+ new_log = "%s.tmp" % (log_file)
+ data = ''
+ try:
+ if llimit :
+ system("tail -n%s %s > %s" % (llimit, log_file, new_log))
+ log_file = new_log
+ with open(log_file, 'r') as f:
+ data = f.read()
+ except Exception as e:
+ data = "data log is empty\n"
+ return Response(data, mimetype='text/plain')
+
+import psycopg2
+DBName='tgbot' #'lifecontrol'
+DBUser='tgbot' #'lifecontrol'
+DBPass=''
+DBPort='6432'
+#DBHost='213.252.97.166'
+DBHost='185.212.88.20'
+def write2log(logfile, msg):
+ with open(logfile, "a") as f:
+ ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
+ f.write("%s: %s\n" % (ts, msg))
+
+@app.route('/drl')
+def get_drug_list():
+ dataval = request.args.get('drp')
+ if not dataval:
+ return Response("не задан шаблон для поиска лекарств", mimetype='text/plain')
+ qs=str('%'+dataval+'%')
+ q="SELECT name_rus FROM drugs WHERE name_rus LIKE '%s'" % qs.upper()
+ write2log('./log/get_drug_list.log', q)
+ conn = psycopg2.connect(dbname=DBName, user=DBUser, password=DBPass, host=DBHost, port=DBPort)
+ cursor = conn.cursor()
+ cursor.execute(q)
+ records = cursor.fetchall()
+ data='По заданному шаблону лекарства не найдены'
+ i=1
+ for r in records:
+ if(i == 1):
+ data=r[0]
+ else:
+ data=data+"\n"+r[0]
+ i=i+1
+ cursor.close()
+ conn.close()
+ #data="АСПИРИН\nПЕНТАЛГИН\nПУРГЕН"
+ return Response(data, mimetype='text/plain')
+
+@app.route('/tgwebapp')
+def tg_webapp():
+ wa_file = "./templates/webapp.html"
+ data = ''
+ try:
+ with open(wa_file, 'r') as f:
+ data = f.read()
+ except Exception as e:
+ data = "webapp file is empty\n"
+ return Response(data, mimetype='text/html')
+
+
+@app.route('/logtail')
+def logtail():
+ try:
+ logname = request.args.get('log')
+ log = "%s/log/%s" % (home_dir, logname)
+ print(log)
+ lcnt=10
+ databuf = Popen(["tail", "-n%i" % lcnt, log], stdout=PIPE, encoding='utf-8').communicate()[0]
+
+ except Exception as e:
+ databuf = "log file is empty or not exist\n"
+ return Response(databuf, mimetype='text/plain')
+
+
+@app.route('/getMenu', methods = ['POST'])
+def getMenu():
+ answ = 'OK'
+ mtype = request.form['menuType']
+ mtitle = request.form['menuTitle']
+ mtext = request.form['menuText']
+ if not mtype:
+ mtype = 'not mtype'
+ answ = 'ERR mtype'
+ if not mtitle:
+ mtitle = 'not mtitle'
+ answ = 'ERR mtitle'
+ if not mtext:
+ mtext = 'not mtext'
+ answ = 'ERR mtext'
+ with open("./tmp/Dima_Menu", 'w') as f:
+ f.write(mtype)
+ f.write("\n============================================\n")
+ f.write(mtitle)
+ f.write("\n============================================\n")
+ f.write(mtext)
+ f.write("\n============ vv request.data vv ============\n")
+ if(request.data):
+ f.write(str(request.data))
+ f.write("\n============================================\n")
+ return answ
+
+# GET ENV and POST data
+@app.route('/envdata', methods = ['POST', 'GET'])
+def envdata():
+ with open("./tmp/env-and-post.data", 'w') as f:
+ if(request.content_type):
+ f.write(str(request.content_type))
+ f.write("\n============================================\n")
+ if(request.headers):
+ for hname in request.headers.keys():
+ f.write("%s: %s\n" % (hname, request.headers[hname]))
+ f.write("\n============================================\n")
+ if(request.data):
+ f.write(str(request.data))
+ f.write("\n============================================\n")
+ if(request.query_string):
+ #f.write("%s" % str(request.query_string))
+ f.write(request.query_string)
+ return 'OK!\n'
+
+
+
+if __name__ == '__main__':
+ app.run()
diff --git a/germany/door2tlg.py b/germany/door2tlg.py
new file mode 100644
index 0000000..3cf5167
--- /dev/null
+++ b/germany/door2tlg.py
@@ -0,0 +1,36 @@
+import datetime
+import argparse
+import telebot
+
+parser = argparse.ArgumentParser(description='send door status')
+parser.add_argument('--did', type=str, default="1", help='door ID')
+parser.add_argument('--ds', type=int, default=0, help='door status')
+parser.add_argument('--dv', type=float, default=0, help='Vbat voltage')
+parser.add_argument('--t', type=float, default=-1, help='Temperature')
+parser.add_argument('--h', type=float, default=-1, help='Humidity')
+parser.add_argument('--tgids', type=str, default="245058979", help='TG IDs list')
+parser.add_argument('--tgtok', type=str, default="5563613923:AAFGYdokQYJfTTQYhJftGZy3KtMDSZg5p6Q", help='TG token')
+args = parser.parse_args()
+
+homebot = telebot.TeleBot(args.tgtok)
+vbat = ''
+
+if(float(args.dv)>=0):
+ vbat = " / Аккумулятор %.2fV" % args.dv
+
+if(float(args.t)!=-1):
+ vbat = "%s / Температура %.2fV" % (vbat, args.t)
+if(float(args.h)!=-1):
+ vbat = "%s / Влажность %.2fV" % (vbat, args.h)
+
+ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
+if(int(args.ds)==0):
+ msg = "Дверь %s. Открытие. %s%s" % (args.did, ts, vbat)
+else:
+ msg = "Дверь %s. Закрытие. %s%s" % (args.did, ts, vbat)
+
+uids = args.tgids.split(",")
+for uid in uids:
+ homebot.send_message(uid, msg)
+
+
diff --git a/germany/make4axelsgraph.py b/germany/make4axelsgraph.py
new file mode 100644
index 0000000..b722f1c
--- /dev/null
+++ b/germany/make4axelsgraph.py
@@ -0,0 +1,156 @@
+import cv2
+import numpy as np
+datadir = "log"
+logid = "2"
+log = "/home/shurik/SmartBed/src/%s/sb_%s.log" % (datadir, logid)
+
+axels4graph=[4, 7, 14, 37, 18]
+maxaxels4graphcnt = 4
+axels4graphcnt = min(maxaxels4graphcnt, len(axels4graph))
+#print(axels4graphcnt)
+
+scale = 5 # увеличение сигнала на графике
+log_lines = 15
+axel_cnt = 39 # количество акселерометров
+steps = 10 # количество измерений в одной строке
+pdCnt = 39 # кол-во датчиков давления
+data_delta = 1 # пропускаем первое значение - таймер
+pd_delta = steps * axel_cnt * 3 + data_delta
+
+input_frm_rates = 17
+log_recs_delta = 1.5 # интервал между записями в логе
+
+pd = []
+ax = [[[],[],[]] for n in range(axel_cnt)]
+times = []
+cc=0
+
+# read data from system pipe
+from subprocess import Popen, PIPE
+databuf = Popen(["tail", "-n%i" % log_lines, log], stdout=PIPE, encoding='utf-8').communicate()[0]
+#print(log)
+#print("databuf:\n", databuf)
+lines = [line.rstrip() for line in databuf.split("\n")]
+
+for l in lines:
+ if len(l) <=1 :
+ break
+ times.append(l.split("\t")[0])
+ args = l.split("\t")[1].split(",")
+ #pd.append([int(args[pd_delta]), int(args[pd_delta+1]), int(args[pd_delta+2]), int(args[pd_delta+3]), int(args[pd_delta+4])])
+ for sn in range(steps):
+ dlt = sn * 3 * axel_cnt
+ for i in range(axel_cnt):
+ # если уберут первое значение (метку таймера), то прибавку надо начинать не с 1, а с 0
+ ax[i][0].append(int(args[dlt + i*3+1]) if int(args[dlt + i*3+1]) < 32768 else int(args[dlt + i*3+1]) - 65536)
+ ax[i][1].append(int(args[dlt + i*3+2]) if int(args[dlt + i*3+2]) < 32768 else int(args[dlt + i*3+2]) - 65536)
+ ax[i][2].append(int(args[dlt + i*3+3])-280 if int(args[dlt + i*3+3]) < 32768 else int(args[dlt + i*3+3]) - 65536)
+ cc+=1
+ #if cc == 2:
+ # print(ax)
+
+ax_shape = np.shape(ax)
+
+axMax = [[0, 0, 0] for n in range(axel_cnt)]
+axMin = [[0, 0, 0] for n in range(axel_cnt)]
+deltaMax = 0
+for ai in range(axel_cnt):
+ for i in range(3):
+ axMax[ai][i] = max(ax[ai][i])
+ axMin[ai][i] = min(ax[ai][i])
+ if axMax[ai][i] == axMin[ai][i]:
+ axMax[ai][i] += 1
+ deltaMax = (axMax[ai][i] - axMin[ai][i]) if (axMax[ai][i] - axMin[ai][i]) > deltaMax else deltaMax
+
+a1,a2,glen = np.shape(ax)
+imH, imW = [1080, 1920]
+image_shape = (imH, imW, 3)
+image = np.zeros(image_shape, dtype=np.uint8)
+
+gpoints = ax_shape[2]
+gphalf = gpoints / 2
+gdelta = 20 # смещение графика от левого/правого края
+hStep = (imH - 10) / (4 / 2) - 10
+wStep = (imW - gdelta*2) / gpoints /2
+pdHStep = (imH - 40) / pdCnt
+hpix = 2 # int(65000 / hStep) # вес одного вертикального пикселя
+
+isClosed = False
+
+c0 = (255, 0, 0)
+c1 = (0, 255, 0)
+c2 = (0, 0, 255)
+
+thickness = 2
+vline = [[imW/2, 20], [imW/2, imH-20]]
+vline = np.array(vline, np.int32).reshape((-1, 1, 2))
+hline = [[20, imH/2], [imW-20, imH/2]]
+hline = np.array(hline, np.int32).reshape((-1, 1, 2))
+
+radius = 20
+color = [(0, 0, 225), (225, 225, 255)]
+aiH = [1, 1, 0, 0]
+aiW = [0, 1, 0, 1]
+
+cnt = 0
+fc = 0
+pdcnt = 0
+ret_val = True
+printflag=True
+gstep = 5
+dsize = 20 # размер анализируемого на движение участка
+msize = 3 # meter size / интервал измерения от текущей точки назад
+body = ["nogi", "ruki", "telo"]
+
+for istep in range(1):
+ image *= 0
+ image -=1
+ acnt = int(cnt / input_frm_rates * (steps / log_recs_delta) )
+ pdcnt = int(acnt/10)
+ dstart = acnt-dsize if acnt> dsize else 0
+ mstart = acnt-msize if acnt> msize else 0
+ gstart = 0 # int((acnt-gphalf) if (acnt>gphalf) else 0)
+ gstop = glen #int((acnt+gphalf) if (acnt<(glen-gphalf)) else glen)
+ chartlen = int(gstop - gstart)
+ ldelta = int(gdelta) #int(gdelta if (gstart>0) else gdelta + (gphalf - acnt)*wStep)
+ ax4ch = [[[],[],[]] for n in range(axels4graphcnt)]
+ j=0
+ for i in range(gstart, gstop):
+ Wval = [int(ldelta + wStep*j) , int(imW/2+ldelta + wStep*j)]
+ for ai in range(axels4graphcnt):
+ #print(ai)
+ ax4ch[ai][0].append([Wval[aiW[ai]], int((ax[axels4graph[ai]][0][i]*scale+80)/hpix + 10 + aiH[ai]*hStep+150)])
+ ax4ch[ai][1].append([Wval[aiW[ai]], int((ax[axels4graph[ai]][1][i]*scale+80)/hpix + 10 + aiH[ai]*hStep+150)])
+ ax4ch[ai][2].append([Wval[aiW[ai]], int((ax[axels4graph[ai]][2][i]*scale+80)/hpix + 10 + aiH[ai]*hStep+150)])
+ j += 1
+ for i in range(axels4graphcnt):
+ ax4ch[i][0] = np.array(ax4ch[i][0], np.int32).reshape((-1, 1, 2))
+ ax4ch[i][1] = np.array(ax4ch[i][1], np.int32).reshape((-1, 1, 2))
+ ax4ch[i][2] = np.array(ax4ch[i][2], np.int32).reshape((-1, 1, 2))
+ for i in range(axels4graphcnt):
+ image = cv2.polylines(image, [ax4ch[i][0]], isClosed, c0, thickness)
+ image = cv2.polylines(image, [ax4ch[i][1]], isClosed, c1, thickness)
+ image = cv2.polylines(image, [ax4ch[i][2]], isClosed, c2, thickness)
+ image = cv2.polylines(image, [vline], isClosed, (200, 200, 200), thickness)
+ image = cv2.polylines(image, [hline], isClosed, (200, 200, 200), thickness)
+ if acnt > 3 :
+ pdsum = np.sum(pd[pdcnt])
+ if pdsum < pdCnt :
+ # считаем, что тело лежит на кровати, т.е. (pdsum < 5)
+ inumax = 0
+ imark = 0
+ for iax in range(12):
+ anum = int (iax / 3) # номер акселя
+ aline = iax % 3 # три оси акселя
+ imin, imax, imean = (np.min(ax[anum][aline][mstart:acnt]), np.max(ax[anum][aline][mstart:acnt]), int(np.mean(ax[anum][aline][dstart:acnt])))
+ if abs(imax - imean) > sens or abs(imean - imin) > sens :
+ inumax += 1
+ imark |= (int(iax/6)+1)
+ for i in range(axels4graphcnt):
+ labH = int(50+imH*aiH[i]/2)
+ labW = int(20+imW*aiW[i]/2)
+ cv2.putText(image, "axel %i" % axels4graph[i], (labW, labH), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
+ imH, imW
+
+ cv2.imwrite("4acsels_chart.png",image)
+
diff --git a/germany/mk_img.py b/germany/mk_img.py
new file mode 100644
index 0000000..a96dd3a
--- /dev/null
+++ b/germany/mk_img.py
@@ -0,0 +1,33 @@
+import matplotlib.pyplot as plt
+
+
+def make_plot(fname, id):
+ with open(fname, 'r') as f:
+ lines = [line.rstrip() for line in f]
+ ax1 = []
+ ax2 = []
+ ax3 = []
+ cnt = 0
+ for l in lines:
+ b = l.split("\t")
+ args = b[1].split(",")
+ ax1.append([cnt, args[0]])
+ ax2.append([cnt, args[1]])
+ ax3.append([cnt, args[2]])
+ cnt += 1
+ ax1 = [list(i) for i in zip(*ax1)]
+ ax2 = [list(i) for i in zip(*ax2)]
+ ax3 = [list(i) for i in zip(*ax3)]
+ plt.figure(figsize=(20,10))
+ plt.title("акселерометр кровати %s" % id, fontsize=20)
+ plt.plot(ax1[0], ax1[1],'g-')
+ plt.plot(ax2[0], ax2[1],'r-')
+ plt.plot(ax3[0], ax3[1],'b-')
+ img_name = "%s_chart.png" % fname
+ plt.savefig(img_name)
+ return(img_name)
+
+fname = './tmp/sb_2'
+id = 2
+img_file = make_plot(fname, id)
+print(img_file)
diff --git a/germany/uwsgi.ini b/germany/uwsgi.ini
new file mode 100644
index 0000000..51446bc
--- /dev/null
+++ b/germany/uwsgi.ini
@@ -0,0 +1,17 @@
+[uwsgi]
+master = true
+chdir=/home/shurik/SmartBed/src
+shared-socket = 0.0.0.0:443
+uid = shurik
+gid = shurik
+
+https = =0,https/fullchain.pem,https/privkey.pem,HIGH
+#http-to = /tmp/uwsgi.sock
+http = 195.201.126.70:8080
+
+buffer-size=32768
+wsgi-file = app.py
+callable = app
+#module=app.py:application
+static-map = /log=/home/shurik/SmartBed/src/log
+