From cb118edc5a978a0c10a18cfd9f69dac4a8ce523f Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Sep 2023 00:33:39 -0400 Subject: [PATCH] websocket every timestep --- .env | 12 +++ DbFuncs/db.py | 241 +++++++++++++++++++++++++++--------------- DbFuncs/db_create.py | 12 ++- DbFuncs/sql.db | Bin 1150976 -> 1150976 bytes ad.py | 9 +- api.py | 157 ++++++++++++++++----------- client.py | 29 ----- config/global_vars.py | 3 + config/utils.py | 16 +-- item.py | 45 +++++--- list.py | 53 +++++++--- main.py | 82 ++++++++++---- commands => readme | 15 ++- 13 files changed, 424 insertions(+), 250 deletions(-) create mode 100644 .env delete mode 100644 client.py create mode 100644 config/global_vars.py rename commands => readme (74%) diff --git a/.env b/.env new file mode 100644 index 0000000..5bdedce --- /dev/null +++ b/.env @@ -0,0 +1,12 @@ +hostName = 'https://212.224.86.112:8443' + +dbPath = './DbFuncs/sql.db' +adPath = '/img/ad.mp4' + +screenX = 600 +screenY = 900 + +itemLength = 220 + +requestTimeStep = 10 + diff --git a/DbFuncs/db.py b/DbFuncs/db.py index b5e7f57..3bff103 100644 --- a/DbFuncs/db.py +++ b/DbFuncs/db.py @@ -1,8 +1,10 @@ import sqlite3 import datetime -from config import utils +# from config import utils import os - +import threading +from dotenv import load_dotenv +load_dotenv() # import os # import sys @@ -15,9 +17,65 @@ from model.Ad import Ad from model.Machine import Machine +dbPath = os.environ.get('dbPath') + + + + +#lock = threading.Lock() +conn = None + +def openDatabase(): + try: + global conn + print("opening") + conn = sqlite3.connect(dbPath) + # Mape value from SQLite's THREADSAFE to Python's DBAPI 2.0 + # threadsafety attribute. + sqlite_threadsafe2python_dbapi = {0: 0, 2: 1, 1: 3} + #conn = sqlite3.connect(dbPath) + threadsafety = conn.execute( + """ + select * from pragma_compile_options + where compile_options like 'THREADSAFE=%' + """ + ).fetchone()[0] + print(threadsafety) + conn.close() + + print("aaa") + + threadsafety_value = int(threadsafety.split("=")[1]) + + if sqlite_threadsafe2python_dbapi[threadsafety_value] == 3: + check_same_thread = False + else: + check_same_thread = True + + conn = sqlite3.connect(dbPath, check_same_thread=check_same_thread) + + print("ok", conn) + + return True + except sqlite3.Error as error: + print('db connection error', error) + + print("aaaaadddd") + return False + +def closeDatabase(): + try: + global conn + if conn: + conn.close() + except sqlite3.Error as error: + print('db closing error', error) + def insert_ads(ad): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() insert_query = """insert into ads (type, content) @@ -32,20 +90,21 @@ def insert_ads(ad): conn.commit() cursor.close() - return True + except sqlite3.Error as error: print('insert_ad_fail', error) return False finally: - if conn: - conn.close() - print('connection is closed') - return False + #if conn: + #conn.close() + print('insert_ad_connection is closed') def insert_machine(machine): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() insert_query = """insert into machines (name, unit, value, thumbnail) @@ -60,71 +119,71 @@ def insert_machine(machine): conn.commit() cursor.close() - return True + except sqlite3.Error as error: print('insert_machine_fail', error) return False finally: - if conn: - conn.close() - print('connection is closed') - return False + print('insert_machine_connection is closed') # insert into product table def insert_product(product): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() insert_query = """insert into products (itemno, name, thumbnail, nicotine, batterypack, tankvolumn, price, currency, caution, stock) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""" # imageBlob = utils.convert_to_blod_data(product.thumbnail) data = (product.itemno, product.name, product.thumbnail, product.nicotine, product.batterypack, - product.tankvolumn, product.price, product.currency, product.caution, product.stock) + product.tankvolumn, product.price, product.currency, product.caution, product.stock) cursor.execute(insert_query, data) print("inserted product successfully") conn.commit() cursor.close() - return True + except sqlite3.Error as error: print('insert_prodcut_fail', error) return False finally: - if conn: - conn.close() - print('connection is closed') - return False + print('insert_prodcut_connection is closed') # update product item def update_product(id, image, price): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() update_query = '''update products set thumbnail = ?, price = ? where id = ?''' - imageBlob = utils.convert_to_blod_data(image) - params = (imageBlob, price, id) + # imageBlob = utils.convert_to_blod_data(image) + params = (image, price, id) cursor.execute(update_query, params) conn.commit() cursor.close() + return True except sqlite3.Error as error: print('update_product_fail', error) + return False finally: - if conn: - conn.close() - print('connection is closed') + print('update_prodcut_connection is closed') # get all products def get_products(): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() select_query = '''select * from products''' @@ -136,50 +195,50 @@ def get_products(): product = convert_to_product(record) products.append(product) - conn.commit() + #conn.commit() cursor.close() + return products except sqlite3.Error as error: print('get_prodcuts_fail', error) - records = [] + return [] finally: - if conn: - conn.close() - print('connection is closed') + print('get_prodcuts_connection is closed') - return products # get product -def get_product(id): +def get_product(itemno): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() - select_query = '''select * from products where id = ?''' - cursor.execute(select_query, (id,)) + select_query = '''select * from products where itemno = ?''' + cursor.execute(select_query, (itemno,)) record = cursor.fetchone() product = None if record: product = convert_to_product(record) - conn.commit() + #conn.commit() cursor.close() + return product + except sqlite3.Error as error: print('get_prodcut_fail', error) - record = None + return None finally: - if conn: - conn.close() - print('connection is closed') - - return product + print('get_product_connection is closed') # get Ad def get_ad(): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() select_query = '''select * from ads''' @@ -190,23 +249,22 @@ def get_ad(): if record: ad = convert_to_ad(record) - conn.commit() + #conn.commit() cursor.close() + return ad except sqlite3.Error as error: print('get_ad_fail', error) - ad = None + return None finally: - if conn: - conn.close() - print('connection is closed') - - return ad + print('get_ad_connection is closed') # get Ad def get_ad_row(id): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() select_query = '''select * from ads where id = ?''' @@ -217,24 +275,23 @@ def get_ad_row(id): if record: ad = convert_to_ad(record) - conn.commit() + #conn.commit() cursor.close() + return ad except sqlite3.Error as error: print('get_ad_fail', error) - ad = None + return None finally: - if conn: - conn.close() - print('connection is closed') - - return ad + print('get_ad_row_connection is closed') # get Ad def get_machines(): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() select_query = '''select * from machines''' @@ -246,44 +303,48 @@ def get_machines(): machine = convert_to_machine(item) machines.append(machine) - conn.commit() + #conn.commit() cursor.close() + return machines except sqlite3.Error as error: print('get_machine_fail', error) + return [] finally: - if conn: - conn.close() - print('connection is closed') - - return machines + print('get_machine_connection is closed') def get_product_count(): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() select_query = '''select count(id) from products ''' cursor.execute(select_query) record = cursor.fetchone() - conn.commit() + cnt = 0 + if record: + cnt = record[0] + + #conn.commit() cursor.close() + return cnt + except sqlite3.Error as error: print('fail', error) - record = None + return None finally: - if conn: - conn.close() - print('connection is closed') - - return record[0] + print('get_prodcut_count_connection is closed') # delete Machines def delete_machines(): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() delete_query = '''delete from machines''' @@ -291,18 +352,20 @@ def delete_machines(): conn.commit() cursor.close() + return True except sqlite3.Error as error: print('delete_machine_fail', error) + return False finally: - if conn: - conn.close() - print('connection is closed') + print('delet_machines_connection is closed') # delete Ads def delete_ads(): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() delete_query = '''delete from ads''' @@ -310,18 +373,20 @@ def delete_ads(): conn.commit() cursor.close() + return True except sqlite3.Error as error: print('delete_ads_fail', error) + return False finally: - if conn: - conn.close() - print('connection is closed') + print('delete_ads_connection is closed') # delete Ads def delete_products(): + try: - conn = sqlite3.connect(utils.dbPath) + global conn + #conn = sqlite3.connect(dbPath) cursor = conn.cursor() delete_query = '''delete from products''' @@ -329,13 +394,13 @@ def delete_products(): conn.commit() cursor.close() + return True except sqlite3.Error as error: print('delete_products_fail', error) + return False finally: - if conn: - conn.close() - print('connection is closed') + print('delte_produts_connection is closed') def convert_to_product(record): product = Product(record[0], record[1], record[2], record[3], record[4], diff --git a/DbFuncs/db_create.py b/DbFuncs/db_create.py index e50b5b5..c1bdb68 100644 --- a/DbFuncs/db_create.py +++ b/DbFuncs/db_create.py @@ -2,20 +2,22 @@ import datetime import os +from dotenv import load_dotenv +load_dotenv() import sys -from config import utils - +dbPath = os.environ.get('dbPath') def create_tables(): create_product_table_if_not_exists() create_ads_table_if_not_exists() create_machine_table_if_not_exists() + #None # create product table def create_product_table_if_not_exists(): try: - conn = sqlite3.connect(utils.dbPath) + conn = sqlite3.connect(dbPath) cursor = conn.cursor() create_product_table_query = '''CREATE TABLE IF NOT EXISTS products ( @@ -48,7 +50,7 @@ def create_product_table_if_not_exists(): # create product table def create_ads_table_if_not_exists(): try: - conn = sqlite3.connect(utils.dbPath) + conn = sqlite3.connect(dbPath) cursor = conn.cursor() create_ads_table_query = '''CREATE TABLE IF NOT EXISTS ads ( @@ -73,7 +75,7 @@ def create_ads_table_if_not_exists(): # create product table def create_machine_table_if_not_exists(): try: - conn = sqlite3.connect(utils.dbPath) + conn = sqlite3.connect(dbPath) cursor = conn.cursor() create_machine_table_query = '''CREATE TABLE IF NOT EXISTS machines ( diff --git a/DbFuncs/sql.db b/DbFuncs/sql.db index 2603e4a4d4355f204fa8672b868fe924f48059e8..5f89176c60c74c630415c8a7462f6f240a7ce4cb 100644 GIT binary patch delta 3720 zcma)D;-(7KgMy`Ol_d!F~#JBOS5OENR}JIOGFl8Qkk6@$v! zMbq{=j%n*SPJ5^>@6tPsSGo@_TT!^k&1m2?)7ovAms9P17bq?84_14-1L;n7>D;NM zBmJ*yyslYk;n^Far6c_2TfA>g3wAi7v><|l?heP@;T~{zC33t?ZZFqlm|*k3h{8!u zX(SkIA1InQp>RsUgBML^389!=Lph0^(p5xe^D`MMisH&`0ESUJFSKI8C z?L)j{-96gid$+-@cYk#El*g8bVhcLOr}&#H!ny9@yjK^W!Q)Ty={)`%pT=X`_!J&H z`nHE@a!s0VbLCv$R=7CBw^eecZ>!}n+j)oFfD>WE)WY?xms+H=(5_z6rk>~ccE77l zoB6g*`)2vJR*o*Q#!J}!EL$XO9cr1dwWw9XR-@JlTh-`h>12&l<2W_tu{Hlak3Meb z2i|FuuoZ0EE@8{iVF_E(*=Rj?fLd!|~7q zdcp~CBJ_fjpf~h^zR(Z)!vGlQIK|E>EKY?yI1NsRGvG`(3kJd2a1NXc=fPk&A1;6k z;UdU~i{TQu6fT1ya5-E7SHe|rHCzKj;ad96bu5O#a2Nq2p#TbD6kHECz-Sl)H^NxB z3C6*Am;gm^Gfad@Fd1~6Oa)yvx_)#e&4gRvR+vTKxeeqJh{0?qh1($xcfg%62kwHq z;U2gb?t}Z`0VsoVco62oL+~&>0`uTecnltg`S1i3Kgq)aSO^vH6fAxPQEQm z{Z&88wSMsUFacr#Hz%gtqcV`RTH;!i)xd*SyJ=sn^ zfr@-0Rk;_pB>5z6Npf#)D{>!hGjd<f&#*-Rmy!xZwlOd+3_v_UkODdh8+LcV}0 zPhP&5ynG3H`BL)oW#r`{uOu&DMP9x-X)U^jygZb=d@XtT zI`Z-`^73%<@(A+sNb+(4dAX3hJc_)0J$d;C^73f%@)+{+jY%6qW68@mk(bAjm&cQr zCy-A0#i&B`-fjUVfOo{0Mn@9(nmu^73Qk<;RmY1I;HdKS5r8lDxctJkDG=al@9y z1ESmN=KU}v&b(ni~J(9$jkXCUiQh$tI5l2$jfV! zHVeH>UVeqV{3>~Q9eH^@dAXXryn(#@8hN>fy!<+O`3>^&M)LBTTWNEnUYgO5 zllkSb^3d#cedE*p3NJFujWp`t;DDLtWUV#RR>a1dP;6!A_%wf3&*;F+bQ6s2?HHfx zukRnt3z>bZawB}w^?X?o62I_e$-nX;%fB&#{5vDae=vgFz=td!Tj-6UGCze{Y zNZOQJG91@tu|7f*9_H}p2$tf=f4KAitdHV(r+;jd%UatU4PBrs90SL~aiGJ8AsezF z6EeUB5BlZs&7v>ceQo*T4z>1*zuj>;M1& delta 3332 zcmXxm3tUuX9>(!=&b$M2W6sPVh_wY6h~kY_(#qQ?YN)K?s*u(iCJK@!8(Co~42k8g z<`8*XNii>YO>`PhriBO@8z^4$lAGgQ@m?C1==40J>*wQqUk)?p_kRxuW(vy(6_yWj zKW3F8B}r~0J^EMDzIzakbV(nwCG&IDaF2(tsrNkgsPEJgcf4H=2@X;3N;>tBq#jb6 z)RTel^az%9q4K!QJjJ5ZJt615IW=?I__y*576o5T88<$A(i;=?HZFyrt+6CTbP@lYSU%_r+@ z1%|aD&bX*f5utiVlGB|M^OVt$({J4K-yAhv?v{3TTA88LG3#iLq&ii-)_g5)>BZ}J z?l<0E9_Meay|cuxyVkNNEiv-?m8!g))(zG%w%uC*|Aa-oZ*QLI`ebY}o`0;Y-)B_jPq!s?soVWv%@78YbKH<`WreCg~|K**b zmvd{j7DRTK?R~;}xN6_>pD*S&M8`CLJpDk%)AsTe1+zO(tK8SIha+#}!0Ti32KRIJ zFn?+jdow}@*rmlUDH-NMr`cRsmRp&T7-7~cyZg6KPIj0qMXuGsZfq$DCT$7#p)LX=|5_F%c`Wt}aaXt?KyxrR^OOcmKBD@yf8(gVPe%c74}u z*4K+cPW_?wVfx@GCBr7?I_&Z;TsQRwuG_EsBFrYG##xyf-^x@h#M;@MnIUG2hj`=H+RR_aEfw-l}?Ky?xojH9s{C$QOy;y{|2tw7YAjZ}`q~ zM@+cQ&^k8CY?K-k^wpBIJ=G{jg?=0!7Nk@=D@V3#6|E2I?<`oGJU;!&j<@P(95hY3i{)kWJKm_3s{e<9=`BjOjg( zWjD;2{$aXhQnR{bV7KEDaaTRDZ8Nhsc71WW`vjC=iJ+K=0rc^8`-Ig zyHoktIjaoe$^t1yBGNKp2R)Iey^yE9k*9r-r+ty9PULAnO!6tAx}R*p3Xv^79&q*BM*%qzFEC*Wl!s2-=b?Ljft9b zzp+M@Kf)}0(j3e}|K$}X@NdjQ=VBH*53|sZF$I!N1m1=PgfvMKS!RfM4qlfo~}lo zu0ftwAWzpKPuC$&*L#HpY(SoFM4oO!o_>Km-Hbe~M4oOzo^C~+dXT4IB2T@@({0F8 z4SD(%@^m}$^lPsO0XvYVJCUc~AWy$Vo>n1GcOg%!k*B+nr!~maTIA_>$kQO?Lt0c* z;KP)qgJkJ|4@!|1;i~9q(K_$69@Obi!;UVI48Q}Lq1*fc$YP17H-X?hf!rpK^p zdK{akC$MSNA1R;2F8KBTyu$WCRivLWOki;e(*zc0us>WDzQ3KtlX<1iuNJD!pvd`> zX@{J@#Wh71uC48i+WXOJFJqA8b2UX9w5oX3sn_$9=K*ZU#tm_I7ceNjh(YNk3`#F! zP}+n+=@krWRcsf-!kuVZdGj3nQ*d zV1Z8?sey$V`v@#7*aybZbWzHE)yjKHCpAk}Rd-ryE^%EJMd!N*dw#c_Q-WmiLFwB; zo^zocO!_uO)mFV0`lND2R;26OcIgzGB3tnzRXKo)jRzL^>7?4Q1v~oGfq`f!CZw$} aG7ZBuq2ag_cz4LH@!P-y5x8i$U;hM4Q>1kO diff --git a/ad.py b/ad.py index 600bb3f..dcfb4d6 100644 --- a/ad.py +++ b/ad.py @@ -15,6 +15,10 @@ import os from io import BytesIO import subprocess +from dotenv import load_dotenv +from config.global_vars import global_ads + +load_dotenv() # import pyglet # from pyglet.media import AVBinSource, StaticMemorySource, Player @@ -27,10 +31,11 @@ def __init__(self, **kwargs): def retrieve_layout(self, dt): ad = db.get_ad() + # ad = global_ads if ad: if ad.type == 'MP4': path = os.path.dirname(__file__) - temp_file = path + '/img/ad.mp4' + temp_file = path + os.environ.get('adPath') utils.write_to_file(ad.content, temp_file) videoPlayerLayout = VideoPlayerLayout(temp_file) @@ -107,5 +112,5 @@ def on_video_touch_up(self, video, touch): # Handle the video player touch up event if video.collide_point(*touch.pos): self.manager.current = 'List' - os.remove(self.temp_file) + # os.remove(self.temp_file) diff --git a/api.py b/api.py index 7653e47..229ebe0 100644 --- a/api.py +++ b/api.py @@ -12,11 +12,19 @@ import base64 import ssl import certifi +import os +import threading +from dotenv import load_dotenv +load_dotenv() +from config.global_vars import global_ads, global_machines, global_produts +from config.utils import lockList -hostName = 'https://212.224.86.112:8443' + +hostName = os.environ.get('hostName') +# requestTimeStep = int(os.environ.get('requestTimeStep')) # def create_connect(): -# ws = create_connection("ws://echo.websocket.events/") +# ws = create_connection("wss://212.224.86.112:8443") # print(ws.recv()) # print("Sending 'Hello, World'...") # ws.send("Hello, World") @@ -26,47 +34,28 @@ # print("Received '%s'" % result) # ws.close() -async def connect_to_server(): - ssl_context = ssl.create_default_context() - ssl_context.load_verify_locations(certifi.where()) - - async with websockets.connect('wss://212.224.86.112:8443', ssl = ssl_context) as websocket: - sendData = {'action': 'MachineConnect'} - await websocket.send(json.dumps(sendData)) - - # Receive data - response = await websocket.recv() - responseData = json.loads(response) - - print(f"Received: {response}") - print(f"Received data: {responseData}") - - if responseData['status']: - while True: - statusData = { - 'action': "MachineSendStatus", - 'payload': { - 'serialno': "123-456-678", - 'temparature': "XXX", - 'token': responseData['token'], - } - } - await websocket.send(json.dumps(statusData)) - statusResponse = await websocket.recv() - statusResponseData = json.loads(statusResponse) - -# asyncio.get_event_loop().run_until_complete(connect_to_server()) +# create_connect() +def send_get_ads_info(): + url = "/api/machine/get_ads_info" + # Send an HTTP GET request to a URL of your choice + response = requests.post(hostName + url, verify=False) -async def connect_and_send(): - async with websockets.connect('wss://example.com/ws') as websocket: - await websocket.send("Hello, server!") + # Check the response status code + if response.status_code == 200: + responseData = response.json() # {status : , message : , details : [{},]} + adData = responseData['details'] + # params = Ad(0, adData['type'], bytes(adData['content'], 'utf-8')) + global_ads = [] + db.delete_ads() + params = Ad(0, adData['type'], base64.b64decode(adData['content'])) + global_ads.append(params) + db.insert_ads(params) + else: + print(f"Request failed with status code: {response.status_code}") -# asyncio.get_event_loop().run_until_complete(connect_and_send()) def send_get_machine_info(): - # delete machine table - db.delete_machines() # Send an HTTP GET request to a URL of your choice url = "/api/machine/get_machine_info" @@ -76,32 +65,20 @@ def send_get_machine_info(): if response.status_code == 200: responseData = response.json() # {status : , message : , details : [{},]} machineData = responseData['details'] + global_machines = [] + # delete machine table + db.delete_machines() for item in machineData: params = Machine(0, item['name'], item['unit'], item['value'], base64.b64decode(item['thumbnail'])) - db.insert_machine(params) - else: - print(f"Request failed with status code: {response.status_code}") - -def send_get_ads_info(): - url = "/api/machine/get_ads_info" - db.delete_ads() - # Send an HTTP GET request to a URL of your choice - response = requests.post(hostName + url, verify=False) + + global_machines.append(params) - # Check the response status code - if response.status_code == 200: - responseData = response.json() # {status : , message : , details : [{},]} - adData = responseData['details'] - # params = Ad(0, adData['type'], bytes(adData['content'], 'utf-8')) - params = Ad(0, adData['type'], base64.b64decode(adData['content'])) - db.insert_ads(params) + db.insert_machine(params) else: print(f"Request failed with status code: {response.status_code}") def send_get_products_info(): url = "/api/machine/get_product_info" - # delete machine table - db.delete_products() # Send an HTTP GET request to a URL of your choice response = requests.post(hostName + url, verify=False) @@ -109,9 +86,13 @@ def send_get_products_info(): # Check the response status code if response.status_code == 200: productData = response.json() # {status : , message : , details : [{},]} + global_produts = [] + # delete products table + db.delete_products() for item in productData: params = Product(0, item['itemno'], item['name'], base64.b64decode(item['thumbnail']), item['nicotine'], item['batterypack'], item['tankvolumn'], item['price'], item['currency'], item['caution'], item['stock']) + global_produts.append(params) db.insert_product(params) else: print(f"Request failed with status code: {response.status_code}") @@ -120,6 +101,64 @@ def send_sell_product(): url = "api/machine/sell_product" -# send_get_machine_info() -# send_get_products_info() -# send_get_ads_info() \ No newline at end of file +async def connect_to_server(): + # ssl_context = ssl.create_default_context() + # ssl_context.load_verify_locations(certifi.where()) + + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + ssl_context.check_hostname = False + ssl_context.verify_mode = ssl.CERT_NONE + + print("wss thread id", threading.get_native_id()) + + try: + async with websockets.connect('wss://212.224.86.112:8443', ssl = ssl_context) as websocket: + print('connected') + sendData = {'action': 'MachineConnect'} + await websocket.send(json.dumps(sendData)) + + # Receive data + response = await websocket.recv() + responseData = json.loads(response) + + print(f"Received data: {responseData}") + + machineConnectStatus = responseData['status'] + token = responseData['token'] + + if machineConnectStatus == 'success': + while True: + statusData = { + 'action': "MachineSendStatus", + 'payload': { + 'serialno': "123-456-678", + 'temparature': "XXX", + 'token': token, + } + } + await websocket.send(json.dumps(statusData)) + statusResponse = await websocket.recv() + statusResponseData = json.loads(statusResponse) + print(f'send_websockrt_every10s') + machineGetStatus = statusResponseData['status'] + machineGetType = statusResponseData['type'] + + if machineGetStatus == 1: + lockList[0].acquire() + if 'ads' in machineGetType: + send_get_ads_info() + if 'machine' in machineGetType: + send_get_machine_info() + if 'product' in machineGetType: + send_get_products_info() + lockList[0].release() + + time.sleep(600) + else: + pass + except: + global_ads = db.get_ad() + global_produts = db.get_products() + global_machines = db.get_machines() + +# asyncio.get_event_loop().run_until_complete(connect_to_server()) \ No newline at end of file diff --git a/client.py b/client.py deleted file mode 100644 index aa59d30..0000000 --- a/client.py +++ /dev/null @@ -1,29 +0,0 @@ -from websocket import create_connection -import requests -import time - -def create_connect(): - ws = create_connection("ws://echo.websocket.events/") - print(ws.recv()) - print("Sending 'Hello, World'...") - ws.send("Hello, World") - print("Sent") - print("Receiving...") - result = ws.recv() - print("Received '%s'" % result) - ws.close() - -def send_vending_status(): - while True: - # Send an HTTP GET request to a URL of your choice - url = "https://example.com" # Replace with the URL you want to request - response = requests.get(url) - - # Check the response status code - if response.status_code == 200: - print("Request successful.") - else: - print(f"Request failed with status code: {response.status_code}") - - # Wait for 5 seconds before sending the next request - time.sleep(5) \ No newline at end of file diff --git a/config/global_vars.py b/config/global_vars.py new file mode 100644 index 0000000..0031aa7 --- /dev/null +++ b/config/global_vars.py @@ -0,0 +1,3 @@ +global_produts = [] +global_machines = [] +global_ads = [] \ No newline at end of file diff --git a/config/utils.py b/config/utils.py index f663df9..b4d5b59 100644 --- a/config/utils.py +++ b/config/utils.py @@ -1,10 +1,10 @@ import os -dbPath = './DbFuncs/sql.db' +# dbPath = './DbFuncs/sql.db' -screenX = 600 -screenY = 900 +# screenX = 600 +# screenY = 900 -itemLength = 220 +# itemLength = 220 # convert image to blob data @@ -20,7 +20,7 @@ def write_to_file(data, filename): file.write(data) print("Stored blob data into: ", filename, "\n") - -# path = os.path.dirname( __file__ ) + '/test.mp4' -# convert_to_blod_data(path) -# utils.write_to_file(product[2], path) \ No newline at end of file +lockList = [] +def initLock(lock): + global lockList + lockList.append(lock) \ No newline at end of file diff --git a/item.py b/item.py index 49849ea..b68d367 100644 --- a/item.py +++ b/item.py @@ -13,40 +13,52 @@ from kivy.graphics import Color, Rectangle, Triangle, Bezier import io import math +from functools import partial from DbFuncs import db from DbFuncs import db_create from model.Product import Product -from config import utils - from kivy.graphics import RoundedRectangle, Color, Line +import os +from dotenv import load_dotenv +from config.utils import lockList +load_dotenv() class ItemScreen(Screen): def __init__(self, **kwargs): super(ItemScreen, self).__init__(**kwargs) self.itemId = None + self.timer = None def set_item_id(self, id): self.itemId = id - self.draw_page(self.itemId) + self.timer = Clock.schedule_interval(self.draw_page, 0.03) - def draw_page(self, id): - product = db.get_product(id) + def draw_page(self, dt): + if lockList[0].acquire(False) == False: + return + product = db.get_product(self.itemId) + lockList[0].release() - # display name - self.draw_title(product.name) + if product: + # display name + self.draw_title(product.name) - # display product (image, price, ...) - self.draw_product_info(product) + # display product (image, price, ...) + self.draw_product_info(product) - # inputMoneyLabel = Label(text='Geld einwerfen') - # self.ids.input_money_button.width = inputMoneyLabel.width - # self.ids.input_money_button.text = inputMoneyLabel.text + # inputMoneyLabel = Label(text='Geld einwerfen') + # self.ids.input_money_button.width = inputMoneyLabel.width + # self.ids.input_money_button.text = inputMoneyLabel.text - self.draw_bigo(product.caution) + self.draw_bigo(product.caution) - self.ids.back_img.bind(on_touch_down = self.on_back_press) + self.ids.back_img.bind(on_touch_down = self.on_back_press) + + #stop clock + if self.timer != None: + self.timer.cancel() def draw_title(self, name): titleLayout = self.ids.title_layout @@ -106,7 +118,6 @@ def draw_bigo(self, cautionText): caution.color = (.1,.1,.1,.5) caution.size_hint_x = None caution.size = (500, caution.height /2 ) - print(f'height:{caution.height}') caution.text_size = (caution.width, None) bigoLayout.add_widget(caution) @@ -114,8 +125,8 @@ def draw_bigo(self, cautionText): # Create an Image widget img = Image(source='./img/bigo.png') # Calculate the position for the image (top-right corner) - image_x = utils.screenX - img.width - 20 - image_y = utils.screenY / 3 - img.height / 2 -100 + image_x = int(os.environ.get('screenX')) - img.width - 20 + image_y = int(os.environ.get('screenY')) / 3 - img.height / 2 -100 # Draw the image on the canvas with bigoLayout.canvas: Rectangle(pos=(image_x, image_y), size=img.size, texture=img.texture) diff --git a/list.py b/list.py index 9386cda..b0a5873 100644 --- a/list.py +++ b/list.py @@ -22,46 +22,61 @@ from DbFuncs import db_create from model.Product import Product -from config import utils from item import ItemScreen +from config.global_vars import global_machines, global_produts +import os +from dotenv import load_dotenv +from config.utils import lockList +load_dotenv() class ListScreen(Screen): - WIDTH = utils.screenX + WIDTH = int(os.environ.get('screenX')) def __init__(self, **kwargs): super(ListScreen, self).__init__(**kwargs) - Clock.schedule_once(self.retrieve_image_layout) + self.timer = Clock.schedule_interval(self.retrieve_image_layout, 0.03) Clock.schedule_once(self.retrieve_up_and_down_image) - Clock.schedule_once(self.retrieve_category_layout) + Clock.schedule_interval(self.retrieve_category_layout, 0.03) # self.imageList = [] + + self.screenX = int(os.environ.get('screenX')) + self.itemLength = int(os.environ.get('itemLength')) + self.productImageHeight = 0 self.scroll_position = 0 - self.scroll_move_dis = utils.itemLength + self.scroll_move_dis = self.itemLength self.scroll_y_dis = 0 self.scroll_y_offset = 0 # prevent to delay, so we can get image_layou and draw dynamically def retrieve_image_layout(self, dt): - image_layout = self.ids.image_layout # Access the image_layout widget + if lockList[0].acquire(False) == False: + return # get all products. - products = self.get_products() + products = db.get_products() + lockList[0].release() + image_layout = self.ids.image_layout # Access the image_layout widget # draw Items if products: # get scroll_y step - # self.scroll_y_dis = 1 / (math.ceil(len(products) / 2) - 1) + # self.scroll_y_dis = 1 / (math.ceil(len(products) / 2) - 1) for product in products: image = self.on_draw_item(product) self.productImageHeight = image.height container = BoxLayout() - lp = (utils.screenX / 2 - utils.itemLength - 10) / 2 + lp = (self.screenX / 2 - self.itemLength - 10) / 2 container.padding = [lp ,10,lp,10] container.size_hint_y = None container.height = image.height + 10 container.add_widget(image) image_layout.add_widget(container) + + #stop clock + if self.timer != None: + self.timer.cancel() else: image_layout.add_widget(Label(text='Image not found', color=(0,0,0,1))) @@ -69,9 +84,6 @@ def retrieve_image_layout(self, dt): rowCnt = math.ceil(len(products) / 2 + 1) image_layout.height = rowCnt * self.productImageHeight + (rowCnt - 1) * 20 - def get_products(self): - products = db.get_products() - return products # draw one image def on_draw_item(self, product): @@ -79,7 +91,7 @@ def on_draw_item(self, product): image_stream = io.BytesIO(product.thumbnail) img = CoreImage(image_stream, ext='png') image.texture = img.texture - image.name = product.id + image.name = product.itemno image.manager = self.manager return image @@ -88,11 +100,11 @@ def on_draw_item(self, product): def retrieve_up_and_down_image(self, dt): up_image = self.ids.up_image up_image.size_hint_x = None - up_image.width = utils.screenX * 2 / 3 + up_image.width = self.screenX * 2 / 3 up_image.bind(on_touch_down = self.on_up_img_click) down_image = self.ids.down_image down_image.size_hint_x = None - down_image.width = utils.screenX * 2 / 3 + down_image.width = self.screenX * 2 / 3 down_image.bind(on_touch_down = self.on_down_img_click) def on_up_img_click(self, instance, touch): @@ -125,9 +137,14 @@ def on_down_img_click(self, instance, touch): ######################################################################## def retrieve_category_layout(self, dt): + if lockList[0].acquire(False) == False: + return + categoryLayout = self.ids.category_layout # Access the image_layout widget machines = db.get_machines() - # machines = db.get_products() + lockList[0].release() + + # machines = global_machines for machine in machines: image = self.on_draw_category_item(machine) categoryLayout.add_widget(image) @@ -161,7 +178,9 @@ class ImageItem(Image): def __init__(self, **kwargs): super(ImageItem, self).__init__(**kwargs) self.manager = None - self.size = (utils.itemLength, utils.itemLength) + self.itemLength = os.environ.get('itemLength') + + self.size = (self.itemLength, self.itemLength) self.size_hint = (None, None) def on_touch_down(self, touch): diff --git a/main.py b/main.py index fcd6669..72d3889 100644 --- a/main.py +++ b/main.py @@ -22,51 +22,89 @@ from model.Product import Product from model.Ad import Ad -from config import utils - from item import ItemScreen from list import ListScreen from ad import AdScreen import os +from dotenv import load_dotenv +load_dotenv() import api +import asyncio +from kivy.clock import Clock +import threading +import time +from config.utils import initLock + +mutex = 0 +# connectThread = threading.Thread(target=api.connect_to_server()) + +def between_callback(): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + + loop.run_until_complete(api.connect_to_server()) + loop.close() -dbFlag = False class WindowManager(ScreenManager): - pass - # def __init__(self, **kwargs): - # super().__init__(**kwargs) - # with self.canvas.before: - # Color(1, 1, 1, 1) # a white color - # self.rect = Rectangle(pos=self.pos, size=self.size) - # self.bind(pos=self.update_rect, size=self.update_rect) - - # def update_rect(self, *args): - # self.rect.pos = self.pos - # self.rect.size = self.size + def __init__(self, **kwargs): + super().__init__(**kwargs) + with self.canvas.before: + Color(1, 1, 1, 1) # a white color + self.rect = Rectangle(pos=self.pos, size=self.size) + self.bind(pos=self.update_rect, size=self.update_rect) + + def update_rect(self, *args): + self.rect.pos = self.pos + self.rect.size = self.size kv = Builder.load_file('./kv/list.kv') + class MainApp(App): # Main Application def build(self): + + print("main thread id", threading.get_native_id()) + initLock(threading.Lock()) + + #connect db + db.openDatabase() + + _thread = threading.Thread(target=between_callback) + _thread.start() + + + width = int(os.environ.get('screenX')) + height = int(os.environ.get('screenY')) + db_create.create_tables() - self.connect_to_server() - Window.size = (utils.screenX, utils.screenY) + print('windownamager') + Window.size = (width, height) + + # asyncio.get_event_loop().run_until_complete(api.connect_to_server()) + sm = WindowManager() sm.add_widget(AdScreen(name='Ad')) sm.add_widget(ListScreen(name='List')) sm.add_widget(ItemScreen(name='Item')) + # Clock.schedule_interval(self.periodic_task, 10) + return sm - # create db and insert data - def connect_to_server(self): - api.send_get_ads_info() - api.send_get_machine_info() - api.send_get_products_info() + # def connect_to_server(self, dt): + # api.connect_to_server() + + async def connect_to_server(self): + await api.connect_to_server() + print('Connected to server') + + def periodic_task(self, dt): + asyncio.create_task(self.connect_to_server()) if __name__ == '__main__': - MainApp().run() \ No newline at end of file + MainApp().run() + db.closeDatabase() \ No newline at end of file diff --git a/commands b/readme similarity index 74% rename from commands rename to readme index 6af2920..e43672b 100644 --- a/commands +++ b/readme @@ -1,3 +1,15 @@ +################ windows ######################### +visit https://www.python.org/downloads/release, download python 3.9 and install it +pip install kivy +pip install Pillow +pip install python-pptx +pip install ffpyplayer + +pip install python-dotenv + + + +################ ubuntu #################### sudo apt update sudo apt upgrade sudo add-apt-repository ppa:deadsnakes/p @@ -27,9 +39,6 @@ apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreame pip3.9 install ffpyplayer - - - ##########run command #######go to your workspace python3.9 main.py \ No newline at end of file