Compare commits
19 Commits
frontend-t
...
master
Author | SHA1 | Date | |
---|---|---|---|
059d45b117 | |||
39b7d25a57 | |||
fc9f1c5c05 | |||
7f90e104d3 | |||
2c3206fc06 | |||
b704aee0fc | |||
99ac2acc0d | |||
6a771c589b | |||
2c60e14260 | |||
21aef6ec6c | |||
20dfa6dcc4 | |||
e1a7c4023b | |||
50a7d8251c | |||
6ae5b811f4 | |||
21d72f17b2 | |||
dcd2ff5b89 | |||
a316374da6 | |||
a034f17a63 | |||
40030c91a1 |
130
0001-admin-All-admin-path-functions-require-an-APIKey.patch
Normal file
130
0001-admin-All-admin-path-functions-require-an-APIKey.patch
Normal file
@ -0,0 +1,130 @@
|
||||
From b08a24bedfb247fd148c48e00ee5d9b544991dfe Mon Sep 17 00:00:00 2001
|
||||
From: HeshamTB <hishaminv@gmail.com>
|
||||
Date: Thu, 14 Apr 2022 07:16:28 +0300
|
||||
Subject: [PATCH] admin: All admin path functions require an APIKey
|
||||
|
||||
Signed-off-by: HeshamTB <hishaminv@gmail.com>
|
||||
---
|
||||
sql_app/auth_helper.py | 10 +++++++++-
|
||||
sql_app/main.py | 19 ++++++++++---------
|
||||
2 files changed, 19 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/sql_app/auth_helper.py b/sql_app/auth_helper.py
|
||||
index a9b866b..12aa271 100644
|
||||
--- a/sql_app/auth_helper.py
|
||||
+++ b/sql_app/auth_helper.py
|
||||
@@ -3,18 +3,22 @@ from typing import Optional
|
||||
from decouple import config
|
||||
from datetime import datetime, timedelta
|
||||
from sqlalchemy.orm import Session
|
||||
-from fastapi import Depends
|
||||
+from fastapi import Depends, Security, HTTPException
|
||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||
+from fastapi.security.api_key import APIKey, APIKeyHeader
|
||||
from . import crud, crypto, schemas
|
||||
import jwt
|
||||
|
||||
import time
|
||||
|
||||
|
||||
JWT_SECRET = config('jwt_secret')
|
||||
JWT_ALGO = config('jwt_algorithm')
|
||||
|
||||
+__API_KEY = config('API_KEY')
|
||||
+__API_KEY_NAME = config('API_KEY_NAME')
|
||||
|
||||
+api_key_header = APIKeyHeader(name=__API_KEY_NAME)
|
||||
|
||||
def create_access_token(data : dict, expires_delta : Optional[timedelta] = None):
|
||||
# TODO: Consider making non-expiring token
|
||||
@@ -33,3 +37,7 @@ def authenticate_user(db: Session, username : str, password : str):
|
||||
return False
|
||||
return crypto.verify_key(password, user.passwd_salt, user.hashed_password)
|
||||
|
||||
+def valid_api_key(key = Security(api_key_header)):
|
||||
+ if not __API_KEY == key:
|
||||
+ raise HTTPException(401, detail="invalid key")
|
||||
+ return
|
||||
diff --git a/sql_app/main.py b/sql_app/main.py
|
||||
index 413db35..9a9434e 100644
|
||||
--- a/sql_app/main.py
|
||||
+++ b/sql_app/main.py
|
||||
@@ -1,5 +1,6 @@
|
||||
from fastapi import Depends, FastAPI, HTTPException, status
|
||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||
+from fastapi.security.api_key import APIKey
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from . import crud, models, schemas, auth_helper
|
||||
@@ -65,31 +66,31 @@ def get_user_details(current_user: schemas.User = Depends(get_current_active_use
|
||||
return current_user
|
||||
|
||||
@app.get("/admin/users/", response_model=List[schemas.User], tags=['Admin'])
|
||||
-def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
||||
+def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db), api_key: APIKey = Depends(auth_helper.valid_api_key)):
|
||||
users = crud.get_users(db, skip=skip, limit=limit)
|
||||
return users
|
||||
|
||||
@app.get("/admin/iotentities/", response_model=List[schemas.IotEntity], tags=['Admin'])
|
||||
-def read_iot_entities(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
||||
+def read_iot_entities(skip: int = 0, limit: int = 100, db: Session = Depends(get_db), api_key: APIKey = Depends(auth_helper.valid_api_key)):
|
||||
iot_entities = crud.get_iot_entities(db, skip=skip, limit=limit)
|
||||
return iot_entities
|
||||
|
||||
# TODO: Can duplicate
|
||||
@app.post("/admin/iotentities/create", response_model=schemas.IotEntity, tags=['Admin'])
|
||||
-def create_iot_entities(iot_entity: schemas.IotEntityCreate, db: Session = Depends(get_db)):
|
||||
+def create_iot_entities(iot_entity: schemas.IotEntityCreate, db: Session = Depends(get_db), api_key: APIKey = Depends(auth_helper.valid_api_key)):
|
||||
iot_entities = crud.create_iot_entity(db, iot_entity)
|
||||
return iot_entities
|
||||
|
||||
@app.get("/admin/users/{user_id}", response_model=schemas.User, tags=['Admin'])
|
||||
-def read_user(user_id: int, db: Session = Depends(get_db)):
|
||||
+def read_user(user_id: int, db: Session = Depends(get_db), api_key: APIKey = Depends(auth_helper.valid_api_key)):
|
||||
db_user = crud.get_user(db, user_id=user_id)
|
||||
if db_user is None:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
return db_user
|
||||
|
||||
# TODO: Can duplicate
|
||||
@app.post("/admin/users/allowdevice/id", tags=['Admin'])
|
||||
-def allow_user_for_iot_entity_by_id(request: schemas.UserAllowForIotEntityRequestByID, db: Session = Depends(get_db)):
|
||||
+def allow_user_for_iot_entity_by_id(request: schemas.UserAllowForIotEntityRequestByID, db: Session = Depends(get_db), api_key: APIKey = Depends(auth_helper.valid_api_key)):
|
||||
user = crud.get_user(db, request.user_id)
|
||||
if not user:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
@@ -105,7 +106,7 @@ def allow_user_for_iot_entity_by_id(request: schemas.UserAllowForIotEntityReques
|
||||
return user
|
||||
|
||||
@app.post("/admin/users/disallowdevice/id", tags=['Admin'])
|
||||
-def disallow_user_for_iot_entity_by_id(request: schemas.UserAllowForIotEntityRequestByID, db: Session = Depends(get_db)):
|
||||
+def disallow_user_for_iot_entity_by_id(request: schemas.UserAllowForIotEntityRequestByID, db: Session = Depends(get_db), api_key: APIKey = Depends(auth_helper.valid_api_key)):
|
||||
user = crud.get_user(db, request.user_id)
|
||||
if not user:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
@@ -122,7 +123,7 @@ def disallow_user_for_iot_entity_by_id(request: schemas.UserAllowForIotEntityReq
|
||||
return
|
||||
|
||||
@app.post("/admin/users/allowdevice/name", tags=['Admin'])
|
||||
-def allow_user_for_iot_entity_by_name(request: schemas.UserAllowForIotEntityRequestByUsername, db: Session = Depends(get_db)):
|
||||
+def allow_user_for_iot_entity_by_name(request: schemas.UserAllowForIotEntityRequestByUsername, db: Session = Depends(get_db), api_key: APIKey = Depends(auth_helper.valid_api_key)):
|
||||
user = crud.get_user_by_username(db, request.username)
|
||||
if not user:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
@@ -138,11 +139,11 @@ def allow_user_for_iot_entity_by_name(request: schemas.UserAllowForIotEntityRequ
|
||||
return
|
||||
|
||||
@app.post("/admin/users/{user_id}/deactiveate", tags=['Admin'])
|
||||
-def deactiveate_user(user_id: int, db:Session = Depends(get_db)):
|
||||
+def deactiveate_user(user_id: int, db:Session = Depends(get_db), api_key: APIKey = Depends(auth_helper.valid_api_key)):
|
||||
return
|
||||
|
||||
@app.post("/admin/users/{user_id}/activeate", tags=['Admin'])
|
||||
-def deactiveate_user(user_id: int, db:Session = Depends(get_db)):
|
||||
+def deactiveate_user(user_id: int, db:Session = Depends(get_db), api_key: APIKey = Depends(auth_helper.valid_api_key)):
|
||||
return
|
||||
|
||||
@app.get("/users/acesslist/", response_model=List[schemas.IotEntity], tags=['Users'])
|
||||
--
|
||||
libgit2 1.4.3
|
||||
|
10
run-tls
10
run-tls
@ -1,4 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
source venv/bin/activate
|
||||
|
||||
cd sql_app/
|
||||
|
||||
./file_permissios.py
|
||||
if [ $? == 1 ]
|
||||
then
|
||||
echo "enviorment file_permissions are incorrect"
|
||||
exit 1
|
||||
fi
|
||||
cd ../
|
||||
exec uvicorn sql_app.main:app --ssl-certfile server.crt --ssl-keyfile server.key --port 4040 --host 0.0.0.0 --no-server-header
|
||||
|
10
sql_app/TODO
10
sql_app/TODO
@ -15,7 +15,7 @@
|
||||
- [X] Expose data analysis
|
||||
- [X] Load backend onto RPi
|
||||
- [X] Test connections in lab network
|
||||
- [ ] Define emrgancy triggers (manual and automatic)
|
||||
- [X] Define emrgancy triggers (manual and automatic)
|
||||
- [ ] Expose temporary control in case of emergancy
|
||||
- Triggers
|
||||
- Acccess
|
||||
@ -36,6 +36,10 @@
|
||||
- [ ] Write unit tests
|
||||
- [ ] Develop a program to visualize the data
|
||||
- [ ] CLI frontend
|
||||
|
||||
|
||||
- [X] Emergaency
|
||||
- [X] Send state with accesslist
|
||||
- [X] Split monitor into different class
|
||||
- [ ] Make a script that adds types, and thier basic database ops?? (avoid writing boiler-plate)
|
||||
- [ ] Make a script that emulates a door and monitor
|
||||
- [ ] Check file premissions on .env file, if global reject
|
||||
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJibHVldG9vdGhfbWFjIjoic3RyaW5nIn0.ELl5AfBR1NdM4_OFhl_SCTm9EMPpqjiCKOSS0CrOJps
|
@ -1,3 +1,5 @@
|
||||
# May 2022
|
||||
# Hesham T. Banafa <hishaminv@gmail.com>
|
||||
|
||||
from typing import Optional
|
||||
from decouple import config
|
||||
@ -56,3 +58,13 @@ def valid_iot_token(token : str, db: Session):
|
||||
mac_signed = payload.get("bluetooth_mac")
|
||||
device = crud.get_iot_entity_by_bluetooth_mac(db, mac_signed)
|
||||
return device
|
||||
|
||||
def valid_monitor_token(token: str, db: Session):
|
||||
try:
|
||||
payload = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGO])
|
||||
except jwt.DecodeError:
|
||||
return None
|
||||
|
||||
mac_signed = payload.get("bluetooth_mac")
|
||||
monitor = crud.get_monitor_bluetooth(db, mac_signed)
|
||||
return monitor
|
||||
|
@ -1,3 +1,6 @@
|
||||
# March 2022
|
||||
# Hesham T. Banafa <hishaminv@gmail.com>
|
||||
|
||||
# CRUD (Create, Read, Update, Delete) from db
|
||||
|
||||
from sqlalchemy import select, join
|
||||
@ -17,7 +20,7 @@ from warnings import warn
|
||||
def get_user(db: Session, user_id: int) -> models.User:
|
||||
return db.query(models.User).get(user_id)
|
||||
|
||||
def get_iot_entity(db: Session, id: int):
|
||||
def get_iot_entity(db: Session, id: int) -> models.IotEntity:
|
||||
return db.query(models.IotEntity).get(id)
|
||||
|
||||
def get_iot_entity_by_description(db: Session, description: str):
|
||||
@ -44,8 +47,12 @@ def get_access_log_for_door_by_door_mac(db: Session, iot_id: str):
|
||||
def get_access_log_for_user_by_id(db: Session, id : str):
|
||||
return db.query(models.DoorAccessLog).filter(models.DoorAccessLog.user_id == id).all()
|
||||
|
||||
def get_room_data_now(db: Session) -> models.RoomSensorData:
|
||||
return db.query(models.RoomSensorData)[-1]
|
||||
# def get_room_data_now(db: Session, door_id: int) -> models.RoomSensorData:
|
||||
# door = get_iot_entity(db, door_id)
|
||||
# monitor : models.Monitors = door.monitor
|
||||
# if not monitor: return -1
|
||||
# if len(monitor.sensor_history) == 0: return -2
|
||||
# return monitor.sensor_history[-1]
|
||||
|
||||
def create_user(db: Session, user: schemas.UserCreate):
|
||||
key = crypto.gen_new_key(user.password)
|
||||
@ -73,6 +80,8 @@ def update_user_password(db: Session, user: models.User, request: schemas.UserUp
|
||||
def get_iot_entities(db: Session, skip: int = 0, limit: int = 100):
|
||||
return db.query(models.IotEntity).offset(skip).limit(limit).all()
|
||||
|
||||
def get_monitors(db: Session, skip: int = 0, limit: int = 100):
|
||||
return db.query(models.Monitors).offset(skip).limit(limit).all()
|
||||
|
||||
def create_iot_entity(db: Session, iot_entity: schemas.IotEntityCreate):
|
||||
db_item = models.IotEntity(bluetooth_mac=iot_entity.bluetooth_mac,
|
||||
@ -82,6 +91,37 @@ def create_iot_entity(db: Session, iot_entity: schemas.IotEntityCreate):
|
||||
db.refresh(db_item)
|
||||
return db_item
|
||||
|
||||
def create_monitor(db: Session, monitor: schemas.IotEntityBase):
|
||||
db_item = models.Monitors(bluetooth_mac=monitor.bluetooth_mac,
|
||||
description=monitor.description)
|
||||
|
||||
db.add(db_item)
|
||||
db.commit()
|
||||
db.refresh(db_item)
|
||||
return db_item
|
||||
|
||||
def get_monitor(db: Session, id: int) -> models.Monitors:
|
||||
return db.query(models.Monitors).get(id)
|
||||
|
||||
def get_monitor_bluetooth(db: Session, bluetooth_mac: str) -> models.Monitors:
|
||||
return db.query(models.Monitors).filter(models.Monitors.bluetooth_mac == bluetooth_mac).first()
|
||||
|
||||
def update_monitor(db: Session, monitor: models.Monitors):
|
||||
db.add(monitor)
|
||||
db.commit()
|
||||
db.refresh(monitor)
|
||||
|
||||
def update_monitor_readings(db: Session, monitor_upadte: schemas.MonitorUpdateReadings, bluetooth_mac: str):
|
||||
monitor = get_monitor_bluetooth(db, bluetooth_mac)
|
||||
monitor.humidity = monitor_upadte.humidity
|
||||
monitor.people = monitor_upadte.people
|
||||
monitor.smoke_sensor_reading = monitor_upadte.smoke_sensor_reading
|
||||
monitor.temperature = monitor_upadte.temperature
|
||||
|
||||
db.add(monitor)
|
||||
db.commit()
|
||||
db.refresh(monitor)
|
||||
|
||||
def create_user_link_to_iot(db: Session, user_id: int, iot_dev_id: int):
|
||||
# Ensure link is not already present and it does not allow duplicates
|
||||
link = db.query(models.UserAuthToIoTDev).filter(models.UserAuthToIoTDev.user_id == user_id).filter(models.UserAuthToIoTDev.iot_id == iot_dev_id).first()
|
||||
@ -168,16 +208,27 @@ def record_door_access_log(db: Session, entry: schemas.DoorAccessLog):
|
||||
db.commit()
|
||||
db.refresh(db_item)
|
||||
|
||||
def record_room_sensor_data(db: Session, entry: schemas.IotMonitorRoomInfo):
|
||||
def record_room_sensor_data(db: Session, entry: schemas.MonitorUpdateReadings,
|
||||
monitor :models.Monitors):
|
||||
db_item = models.RoomSensorData(humidity=entry.humidity,
|
||||
people=entry.people,
|
||||
temperature=entry.temperature,
|
||||
smoke_sensor_reading=entry.smoke_sensor_reading,
|
||||
timestamp=datetime.now())
|
||||
timestamp=datetime.now(),
|
||||
monitor_id=monitor.id)
|
||||
db.add(db_item)
|
||||
db.commit()
|
||||
db.refresh(db_item)
|
||||
|
||||
monitor.humidity = entry.humidity
|
||||
monitor.temperature = entry.temperature
|
||||
monitor.people = entry.people
|
||||
monitor.smoke_sensor_reading = entry.smoke_sensor_reading
|
||||
|
||||
db.add(monitor)
|
||||
db.commit()
|
||||
db.refresh(monitor)
|
||||
|
||||
def increment_door_access_list_counter(db: Session, iot_entity: models.IotEntity):
|
||||
iot_entity.acces_list_counter = iot_entity.acces_list_counter + 1
|
||||
db.add(iot_entity)
|
||||
@ -190,12 +241,25 @@ def record_user_connection(db: Session, user: models.User, time: datetime):
|
||||
db.commit()
|
||||
db.refresh(entry)
|
||||
|
||||
def get_sensor_data_for_room(db: Session, skip: int = 0, limit: int = 100):
|
||||
data = db.query(models.RoomSensorData).offset(skip).limit(limit).all()
|
||||
return data
|
||||
# def get_sensor_data_for_room(db: Session, monitor_id: int, count_last: int):
|
||||
# data = db.query(models.RoomSensorData).all()
|
||||
# if not data or len(data) == 0: return -1
|
||||
# return data[-count_last]
|
||||
|
||||
def update_user_status(db: Session, user: models.User, state: bool):
|
||||
user.is_active = state
|
||||
db.add(user)
|
||||
db.commit()
|
||||
db.refresh(user)
|
||||
|
||||
def record_emergancy_entry(db: Session, monitor_data: schemas.MonitorUpdateReadings, monitor_id: int):
|
||||
new_entry : models.EmergancyNotice = models.EmergancyNotice(
|
||||
monitor_id=monitor_id,
|
||||
people=monitor_data.people,
|
||||
temperature=monitor_data.temperature,
|
||||
smoke_sensor_reading=monitor_data.smoke_sensor_reading,
|
||||
timestamp=datetime.now()
|
||||
)
|
||||
db.add(new_entry)
|
||||
db.commit()
|
||||
db.refresh(new_entry)
|
||||
|
@ -1,3 +1,5 @@
|
||||
# March 2022
|
||||
# Hesham T. Banafa <hishaminv@gmail.com>
|
||||
|
||||
import os
|
||||
from hashlib import pbkdf2_hmac
|
||||
|
@ -1,3 +1,6 @@
|
||||
# March 2022
|
||||
# Hesham T. Banafa <hishaminv@gmail.com>
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
45
sql_app/enroll_door.py
Normal file
45
sql_app/enroll_door.py
Normal file
@ -0,0 +1,45 @@
|
||||
# Quick enroll new device
|
||||
# Hesham T. Banafa
|
||||
# Jun 12th, 2022
|
||||
|
||||
from decouple import config
|
||||
import requests
|
||||
|
||||
# idk if this stays in memory...
|
||||
headers = {
|
||||
"accept": "application/json",
|
||||
"Content-type": "application/json"
|
||||
}
|
||||
def main():
|
||||
|
||||
if len(sys.argv) != 4:
|
||||
print_help()
|
||||
exit(1)
|
||||
|
||||
device_type = sys.argv[1]
|
||||
bluetooth_mac = sys.argv[2]
|
||||
description = sys.argv[3]
|
||||
if device_type == 'DOOR':
|
||||
mkdoor(bluetooth_mac, description)
|
||||
elif device_type == 'MONITOR':
|
||||
mkmonitor(bluetooth_mac, description)
|
||||
else:
|
||||
print('Device type not DOOR or MONITOR', file=sys.stderr)
|
||||
exit(1)
|
||||
# gen print token of bluetooth_mac
|
||||
print(create_iot_dev_token(bluetooth_mac))
|
||||
|
||||
def mkdoor(bluetooth_mac: str, description: str):
|
||||
data = {
|
||||
"bluetooth_mac": bluetooth_mac,
|
||||
"description": description
|
||||
}
|
||||
|
||||
#response = requests.post("")
|
||||
|
||||
def mkmonitor(bluetooth_mac: str, description: str):
|
||||
pass
|
||||
|
||||
def print_help():
|
||||
msg = 'usgae: enroll_iotdevice <DOOR|MONITOR> <bluetooth_mac> <description>'
|
||||
print(msg)
|
18
sql_app/file_permissios.py
Executable file
18
sql_app/file_permissios.py
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/python
|
||||
|
||||
# Hesham T. Banafa
|
||||
# Jun 12th, 2022
|
||||
# Check enviorment file permissions and return -1 if fails or 0
|
||||
|
||||
import os
|
||||
import stat
|
||||
|
||||
ENV_FILE='.env'
|
||||
|
||||
st = os.stat(ENV_FILE)
|
||||
if st.st_mode & stat.S_IROTH or \
|
||||
st.st_mode & stat.S_IWOTH or \
|
||||
st.st_mode & stat.S_IXOTH:
|
||||
exit(1)
|
||||
|
||||
exit(0)
|
@ -1,3 +1,5 @@
|
||||
# June 2022
|
||||
# Hesham T. Banafa <hishaminv@gmail.com>
|
||||
|
||||
from . import crud, main, schemas, auth_helper
|
||||
from decouple import config
|
||||
@ -55,17 +57,18 @@ def init_door():
|
||||
crud.create_iot_entity(db, iot_door)
|
||||
|
||||
def init_monitor():
|
||||
iot_monitor = schemas.IotEntityCreate(bluetooth_mac="ff:ff:00:ff",
|
||||
iot_monitor = schemas.IotEntityCreate(bluetooth_mac="ff:ff:ff",
|
||||
description="Iot Lab Monitor")
|
||||
monitor_exists = crud.get_iot_entity_by_bluetooth_mac(db, iot_monitor.bluetooth_mac)
|
||||
monitor_exists = crud.get_monitor_bluetooth(db, iot_monitor.bluetooth_mac)
|
||||
if monitor_exists: return
|
||||
crud.create_iot_entity(db, iot_monitor)
|
||||
crud.create_monitor(db, iot_monitor)
|
||||
|
||||
def init_allowance():
|
||||
crud.create_user_link_to_iot(db, 1, 1)
|
||||
|
||||
def init_sensor_data():
|
||||
|
||||
monitor = crud.get_monitor(db, 1)
|
||||
if monitor.sensor_history: return
|
||||
for i in range(50):
|
||||
room_data = \
|
||||
schemas.\
|
||||
@ -75,10 +78,11 @@ def init_sensor_data():
|
||||
temperature=randint(18, 27),
|
||||
smoke_sensor_reading=randint(150, 700),
|
||||
token='dummy')
|
||||
crud.record_room_sensor_data(db, room_data)
|
||||
crud.record_room_sensor_data(db, room_data, monitor)
|
||||
|
||||
def init_open_close_requests():
|
||||
user = crud.get_user_by_email(db, "hisham@banafa.com.sa")
|
||||
if user.access_log: return
|
||||
crud.set_open_door_request(db, 1, 10)
|
||||
log_entry = schemas.DoorAccessLog(user_id=user.id,
|
||||
iot_id=1,
|
||||
@ -115,6 +119,11 @@ def init_user_connections():
|
||||
crud.record_user_connection(db, users[i], datetime.now())
|
||||
crud.record_user_connection(db, users[i], datetime.now())
|
||||
|
||||
def init_link_room_monitor():
|
||||
monitor = crud.get_monitor(db, 1)
|
||||
door = crud.get_iot_entity(db, 1)
|
||||
monitor.door = door
|
||||
crud.update_monitor(db, monitor)
|
||||
|
||||
def init():
|
||||
init_user()
|
||||
@ -124,4 +133,5 @@ def init():
|
||||
init_sensor_data()
|
||||
init_open_close_requests()
|
||||
init_user_connections()
|
||||
init_link_room_monitor()
|
||||
|
@ -16,3 +16,5 @@ then
|
||||
exit 255
|
||||
fi
|
||||
echo "first_user_pass=$firstpass" >> .env
|
||||
|
||||
chmod 600 .env
|
||||
|
140
sql_app/main.py
140
sql_app/main.py
@ -1,14 +1,15 @@
|
||||
from fastapi import Depends, FastAPI, HTTPException, status, Request
|
||||
# March 2022
|
||||
# Hesham T. Banafa <hishaminv@gmail.com>
|
||||
|
||||
from fastapi import Depends, FastAPI, HTTPException, status
|
||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm, OAuth2AuthorizationCodeBearer
|
||||
from fastapi.security.api_key import APIKey
|
||||
from fastapi.responses import PlainTextResponse
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from . import crud, models, schemas, auth_helper, init_db
|
||||
from .database import SessionLocal, engine
|
||||
from .utils import get_db
|
||||
from .utils import get_db, EMERG_SMOKE, EMERG_TEMP, EMERG_OPEN_TIME_SEC
|
||||
|
||||
from typing import List
|
||||
from datetime import timedelta, datetime
|
||||
@ -18,16 +19,11 @@ models.Base.metadata.create_all(bind=engine)
|
||||
oauth = OAuth2PasswordBearer(tokenUrl="tkn")
|
||||
|
||||
app = FastAPI(title="IoT Building System")
|
||||
app.mount("/sql_app/static", StaticFiles(directory="sql_app/static"), name="static")
|
||||
templates = Jinja2Templates(directory="sql_app/templates")
|
||||
|
||||
# Split into endpoints modules
|
||||
#app.include_router(users.router,prefix="/users", tags=["User"])
|
||||
init_db.init()
|
||||
|
||||
@app.get("/")
|
||||
def home(request: Request):
|
||||
return templates.TemplateResponse("home.html", context={"request": request})
|
||||
|
||||
def get_current_user(token: str = Depends(oauth), db: Session = Depends(get_db)):
|
||||
credentials_exception = HTTPException(
|
||||
@ -142,22 +138,23 @@ def get_iot_access_list_for_user(db: Session = Depends(get_db), current_user: sc
|
||||
user = crud.get_user_by_username(db, current_user.username)
|
||||
access_list = list()
|
||||
for device in user.authorized_devices:
|
||||
dev_db : models.IotEntity = device
|
||||
sensors = crud.get_room_data_now(db)
|
||||
if not sensors: raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
door : models.IotEntity = device
|
||||
monitor : models.Monitors = door.monitor
|
||||
if not monitor: raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="No Room link")
|
||||
entry : schemas.RoomOverview = schemas.RoomOverview(
|
||||
id=dev_db.id,
|
||||
description=dev_db.description,
|
||||
bluetooth_mac=dev_db.bluetooth_mac,
|
||||
open_request=dev_db.open_request,
|
||||
time_seconds=dev_db.time_seconds,
|
||||
acces_list_counter=dev_db.acces_list_counter,
|
||||
humidity=sensors.humidity,
|
||||
people=sensors.people,
|
||||
temperature=sensors.temperature,
|
||||
smoke_sensor_reading=sensors.smoke_sensor_reading,
|
||||
force_close=dev_db.force_close
|
||||
id=door.id,
|
||||
description=door.description,
|
||||
bluetooth_mac=door.bluetooth_mac,
|
||||
open_request=door.open_request,
|
||||
time_seconds=door.time_seconds,
|
||||
acces_list_counter=door.acces_list_counter,
|
||||
humidity=monitor.humidity,
|
||||
people=monitor.people,
|
||||
temperature=monitor.temperature,
|
||||
smoke_sensor_reading=monitor.smoke_sensor_reading,
|
||||
force_close=door.force_close,
|
||||
state=door.state
|
||||
)
|
||||
access_list.append(entry)
|
||||
#crud.record_user_connection(db, user, datetime.now())
|
||||
@ -198,12 +195,23 @@ def read_iot_entities(skip: int = 0, limit: int = 100, db: Session = Depends(get
|
||||
iot_entities = crud.get_iot_entities(db, skip=skip, limit=limit)
|
||||
return iot_entities
|
||||
|
||||
@app.get("/admin/monitors/", response_model=List[schemas.Monitor], tags=['Admin'])
|
||||
def read_iot_monitors(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
||||
monitors = crud.get_monitors(db, skip=skip, limit=limit)
|
||||
return monitors
|
||||
|
||||
# TODO: Can duplicate
|
||||
@app.post("/admin/iotentities/create", response_model=schemas.IotEntity, tags=['Admin'])
|
||||
def create_iot_entities(iot_entity: schemas.IotEntityCreate, db: Session = Depends(get_db)):
|
||||
iot_entities = crud.create_iot_entity(db, iot_entity)
|
||||
return iot_entities
|
||||
|
||||
@app.post("/admin/monitor/create", response_model=schemas.Monitor, tags=['Admin'])
|
||||
def create_monitor(iot_entity: schemas.IotEntityBase,
|
||||
db: Session = Depends(get_db)):
|
||||
monitor = crud.create_monitor(db, iot_entity)
|
||||
return monitor
|
||||
|
||||
@app.get("/admin/users/{user_id}", response_model=schemas.User, tags=['Admin'])
|
||||
def read_user(user_id: int, db: Session = Depends(get_db)):
|
||||
db_user = crud.get_user(db, user_id=user_id)
|
||||
@ -282,13 +290,22 @@ def deactiveate_user(user_id: int, db:Session = Depends(get_db)):
|
||||
crud.update_user_status(db, user, True)
|
||||
|
||||
@app.post("/admin/iotdevice/gentoken/", response_model=schemas.Token, tags=['Admin'])
|
||||
def generate_token_for_iot_device(bluetooth_mac : schemas.IotBluetoothMac,
|
||||
api_key: APIKey = Depends(auth_helper.valid_api_key)):
|
||||
def generate_token_for_iot_device(bluetooth_mac : schemas.IotBluetoothMac):
|
||||
# api_key: APIKey = Depends(auth_helper.valid_api_key)
|
||||
# We get here after a valid admin key, so send back permenant token
|
||||
data = {"bluetooth_mac": bluetooth_mac.bluetooth_mac}
|
||||
tkn = auth_helper.create_iot_dev_token(data)
|
||||
return {"access_token": tkn, "token_type": "bearer"}
|
||||
|
||||
@app.patch("/admin/link/monitor/{monitor_id}/door/{door_id}", tags=['Admin'])
|
||||
def link_monitor_with_door(monitor_id: int, door_id: int,
|
||||
db: Session = Depends(get_db)):
|
||||
monitor = crud.get_monitor(db, monitor_id)
|
||||
door = crud.get_iot_entity(db, door_id)
|
||||
monitor.door = door
|
||||
crud.update_monitor(db, monitor)
|
||||
return monitor
|
||||
|
||||
@app.post("/admin/user/accesslog/email/", tags=['Admin'])
|
||||
def get_access_log_history_for_user(request : schemas.UserAccessLogRequestEmail,
|
||||
db : Session = Depends(get_db)):
|
||||
@ -303,14 +320,49 @@ def get_access_log_history_for_user(request : schemas.UserAccessLogRequestUserna
|
||||
if not user: raise HTTPException(status.HTTP_404_NOT_FOUND, detail="User not found")
|
||||
return user.access_log
|
||||
|
||||
@app.get("/admin/roominfo/now/", tags=['Admin'])
|
||||
def get_room_data(db: Session = Depends(get_db)):
|
||||
return crud.get_room_data_now(db)
|
||||
@app.get("/admin/roominfo/{door_id}/now", tags=['Admin'])
|
||||
def get_room_data(door_id: int, db: Session = Depends(get_db)):
|
||||
door = crud.get_iot_entity(db, door_id)
|
||||
if not door:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Door not found")
|
||||
monitor : models.Monitors = door.monitor
|
||||
if not monitor:
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="No Room link")
|
||||
data = monitor.sensor_history
|
||||
if not data or len(data) == 0:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No Sensor data")
|
||||
return data[-1]
|
||||
|
||||
@app.get("/admin/roominfo/history/sensors", tags=['Admin'])
|
||||
def get_all_sensor_history(skip: int = 0, limit: int = 100,
|
||||
@app.get("/admin/roominfo/{monitor_id}/now", tags=['Admin'])
|
||||
def get_room_data(monitor_id: int, db: Session = Depends(get_db)):
|
||||
monitor = crud.get_monitor(db, monitor_id)
|
||||
if not monitor: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Monitor not found")
|
||||
if not monitor.door_id:
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Monitor not linked")
|
||||
|
||||
data = crud.get_room_data_now(db, monitor.door_id)
|
||||
if data == -1: raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="No Room link")
|
||||
if data == -2: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No Sensor data")
|
||||
return data
|
||||
|
||||
@app.get("/admin/roominfo/{monitor_id}/last/{count}", tags=['Admin'])
|
||||
def get_all_sensor_history(monitor_id: int, count: int,
|
||||
db: Session = Depends(get_db)):
|
||||
return crud.get_sensor_data_for_room(db, skip, limit)
|
||||
monitor = crud.get_monitor(db, monitor_id)
|
||||
if not monitor: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Monitor not found")
|
||||
data = monitor.sensor_history
|
||||
if not data or len(data) == 0:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No Sensor data")
|
||||
return data[-count:]
|
||||
|
||||
@app.post("/admin/roominfo/accesslog",response_model=List[schemas.DoorAccessLog], tags=['Admin'])
|
||||
def get_access_log_for_door(request : schemas.AccessLogRequest,
|
||||
@ -333,23 +385,33 @@ def polling_method_for_iot_entity(request: schemas.IotDoorPollingRequest,
|
||||
open_command=device.open_request,
|
||||
acces_list_counter=device.acces_list_counter,
|
||||
time_seconds=device.time_seconds,
|
||||
force_close=device.force_close)
|
||||
force_close=device.force_close,
|
||||
state=device.state)
|
||||
# Reset open_request to False
|
||||
crud.clear_open_door_request(db, device.id)
|
||||
crud.clear_close_door_request(db, device.id)
|
||||
crud.set_door_state(db, device, device.state)
|
||||
crud.set_door_state(db, device, bool(request.state))
|
||||
|
||||
return response
|
||||
|
||||
@app.post("/iotdevice/monitor/status", tags=['Iot'])
|
||||
def polling_method_for_room_monitor(request: schemas.IotMonitorRoomInfo,
|
||||
def polling_method_for_room_monitor(request: schemas.MonitorUpdateReadings,
|
||||
db: Session = Depends(get_db)):
|
||||
device : schemas.IotEntity = auth_helper.valid_iot_token(request.token, db)
|
||||
device : models.Monitors = auth_helper.valid_monitor_token(request.token, db)
|
||||
if not device:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Could not validate credentials")
|
||||
crud.record_room_sensor_data(db, request)
|
||||
crud.record_room_sensor_data(db, request, device)
|
||||
if request.temperature >= EMERG_TEMP or request.smoke_sensor_reading >= EMERG_SMOKE:
|
||||
print("********EMERGENCY AT %s********" % device.description)
|
||||
door : models.IotEntity = device.door
|
||||
print("********OPENING DOOR %s ID:%d********" % (door.description, door.id))
|
||||
crud.set_open_door_request(db, door.id, EMERG_OPEN_TIME_SEC)
|
||||
crud.record_emergancy_entry(db, request, device.id)
|
||||
# Call into a hook to notify with room and people
|
||||
|
||||
print(request)
|
||||
return request
|
||||
|
||||
@app.post("/iotdevice/door/users", response_class=PlainTextResponse, tags=['Iot'])
|
||||
@ -383,3 +445,9 @@ def get_allowed_usernames(request: schemas.IotDoorPollingRequest,
|
||||
tkns = tkns + db_user.last_token + '\n'
|
||||
|
||||
return tkns
|
||||
|
||||
@app.get("/test")
|
||||
def get(db: Session = Depends(get_db)):
|
||||
mon = crud.get_monitor(db, "ff:ff:ff:ff")
|
||||
|
||||
return mon.door
|
||||
|
@ -1,3 +1,6 @@
|
||||
# March 2022
|
||||
# Hesham T. Banafa <hishaminv@gmail.com>
|
||||
|
||||
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, DateTime
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
@ -23,7 +26,7 @@ class IotEntity(Base):
|
||||
__tablename__ = "iot_entities"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
bluetooth_mac = Column(String(512))
|
||||
bluetooth_mac = Column(String(512), index=True, unique=True)
|
||||
description = Column(String(512))
|
||||
open_request = Column(Boolean, default=False)
|
||||
time_seconds = Column(Integer, default=10)
|
||||
@ -31,7 +34,22 @@ class IotEntity(Base):
|
||||
force_close = Column(Boolean, default=False)
|
||||
state = Column(Boolean, default=False) # True is open, False is closed
|
||||
authorized_users = relationship("User", secondary="user_iot_link", back_populates="authorized_devices")
|
||||
access_log = relationship("DoorAccessLog", back_populates="iot_device")
|
||||
access_log = relationship("DoorAccessLog", back_populates="iot_device") # one-to-many
|
||||
monitor = relationship("Monitors", back_populates="door", uselist=False) # one-to-one
|
||||
|
||||
class Monitors(Base):
|
||||
__tablename__ = "monitors"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
bluetooth_mac = Column(String(512), index=True, unique=True)
|
||||
description = Column(String(512))
|
||||
humidity = Column(Integer, default=0)
|
||||
people = Column(Integer, default=0)
|
||||
temperature = Column(Integer, default=0)
|
||||
smoke_sensor_reading = Column(Integer, default=0)
|
||||
door_id = Column(Integer, ForeignKey("iot_entities.id"))
|
||||
door = relationship("IotEntity", back_populates="monitor")
|
||||
sensor_history = relationship("RoomSensorData", back_populates="monitor")
|
||||
|
||||
class UserAuthToIoTDev(Base):
|
||||
__tablename__ = "user_iot_link"
|
||||
@ -54,13 +72,14 @@ class DoorAccessLog(Base):
|
||||
class RoomSensorData(Base):
|
||||
__tablename__ = "room_sensor_data"
|
||||
|
||||
# Data is now not related to a room. We should have a construct for rooms
|
||||
reading_id = Column(Integer, primary_key=True, index=True)
|
||||
humidity = Column(Integer)
|
||||
people = Column(Integer)
|
||||
temperature = Column(Integer)
|
||||
smoke_sensor_reading = Column(Integer)
|
||||
timestamp = Column(DateTime)
|
||||
monitor_id = Column(Integer, ForeignKey("monitors.id"), index=True)
|
||||
monitor = relationship("Monitors", back_populates="sensor_history")
|
||||
|
||||
class UserConnectionHistory(Base):
|
||||
__tablename__ = "user_connection_history"
|
||||
@ -70,4 +89,14 @@ class UserConnectionHistory(Base):
|
||||
timestamp = Column(DateTime)
|
||||
# TODO: add ip
|
||||
|
||||
class EmergancyNotice(Base):
|
||||
__tablename__ = "emergency_notice"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
monitor_id = Column(Integer, ForeignKey("monitors.id"), index=True)
|
||||
people = Column(Integer)
|
||||
temperature = Column(Integer)
|
||||
smoke_sensor_reading = Column(Integer)
|
||||
timestamp = Column(DateTime)
|
||||
|
||||
# TODO: Add table to store active sessions. May periodically clear.
|
@ -1,3 +1,6 @@
|
||||
# March 2022
|
||||
# Hesham T. Banafa <hishaminv@gmail.com>
|
||||
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
@ -28,12 +31,33 @@ class IotEntity(IotEntityBase):
|
||||
time_seconds: int
|
||||
force_close: bool
|
||||
acces_list_counter: int
|
||||
state: bool
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
class IotBluetoothMac(BaseModel):
|
||||
bluetooth_mac : str
|
||||
|
||||
class Monitor(IotEntityBase):
|
||||
# bluetooth_mac: str
|
||||
# description: str
|
||||
id: int
|
||||
bluetooth_mac: str
|
||||
description: str
|
||||
humidity: int
|
||||
people: int
|
||||
temperature: int
|
||||
smoke_sensor_reading: int
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
class MonitorUpdateReadings(BaseModel):
|
||||
humidity : int
|
||||
people : int
|
||||
temperature : int
|
||||
smoke_sensor_reading : int
|
||||
token: str # Contains mac
|
||||
|
||||
class User(UserBase):
|
||||
id: int
|
||||
is_active: bool
|
||||
@ -83,6 +107,7 @@ class IotDoorPollingResponse(BaseModel):
|
||||
acces_list_counter : int
|
||||
time_seconds : int
|
||||
force_close: bool
|
||||
state: bool
|
||||
|
||||
class IotMonitorRoomInfo(BaseModel):
|
||||
humidity : int
|
||||
@ -90,8 +115,8 @@ class IotMonitorRoomInfo(BaseModel):
|
||||
temperature : int
|
||||
smoke_sensor_reading : int
|
||||
token: str
|
||||
class Config:
|
||||
orm_mode = True
|
||||
# class Config:
|
||||
# orm_mode = True
|
||||
|
||||
class IotMonitorRoomInfoTimestamped(IotMonitorRoomInfo):
|
||||
time: datetime
|
||||
|
@ -1,20 +0,0 @@
|
||||
/* custom css */
|
||||
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
padding-top: 2rem;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
@ -1,36 +0,0 @@
|
||||
|
||||
(function () {
|
||||
console.log("Sanity Check!");
|
||||
})()
|
||||
|
||||
var token = null;
|
||||
var logged_in = false;
|
||||
|
||||
function handleLogInClick() {
|
||||
|
||||
var username = document.getElementById("username_box").value;
|
||||
var password = document.getElementById("password_box").value;
|
||||
console.log("Username ", username);
|
||||
|
||||
fetch('/users/tkn', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-type': 'application/x-www-form-urlencoded',
|
||||
'accept': 'application/json'
|
||||
},
|
||||
body: `grant_type=&username=${username}&password=${password}&scope=&client_id=&client_secret=`
|
||||
})
|
||||
.then(response => {
|
||||
if (!response) {
|
||||
throw new Error("HTTP error " + response.status);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(json => {
|
||||
console.log(json);
|
||||
token = json['access_token'];
|
||||
console.log(token);
|
||||
if (token) { logged_in = true; }
|
||||
})
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>IoT Building System</title>
|
||||
<!-- meta -->
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<!-- styles -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css">
|
||||
<link href="{{url_for('static', path='/main.css')}}" rel="stylesheet" media="screen">
|
||||
{% block css %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<!-- child template -->
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
{% include 'footer.html' %}
|
||||
|
||||
<!-- scripts -->
|
||||
<script src="{{url_for('static', path='/main.js')}}" type="text/javascript"></script>
|
||||
{% block js %}{% endblock %}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,6 +0,0 @@
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<small><span class="text-muted">© <a href="https://testdriven.io">TestDriven.io</a></span></small>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -1,37 +0,0 @@
|
||||
{% extends "_base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="starter-template">
|
||||
<h1>IoT Building System</h1>
|
||||
<hr><br>
|
||||
<div>
|
||||
<h3>Task</h3>
|
||||
<p>Login</p>
|
||||
<div class="login_form" role="group" aria-label="Basic example">
|
||||
<form>
|
||||
<input type="text" id="username_box" placeholder="Username">
|
||||
<input type="password" id="password_box" placeholder="Password">
|
||||
<input type="button"value="Login" class="btn btn-primary" onclick="handleLogInClick()">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<br><br>
|
||||
<div>
|
||||
<h3>Task Status</h3>
|
||||
<br>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Status</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tasks">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
40
sql_app/tools/emulate_door.py
Normal file
40
sql_app/tools/emulate_door.py
Normal file
@ -0,0 +1,40 @@
|
||||
# EE495
|
||||
# Hesham T. Banafa
|
||||
# Jun 11th, 2022
|
||||
|
||||
from time import sleep
|
||||
import requests
|
||||
|
||||
|
||||
def poll(poll_url: str, data: dict, headers: dict) -> dict:
|
||||
res : requests.Response = \
|
||||
requests.post(poll_url, json=data, headers=headers)
|
||||
#print('sent ', data)
|
||||
print(res.text, res, res.reason)
|
||||
if res.status_code != 200: return None
|
||||
return res.json()
|
||||
|
||||
def emulate(poll_url, token_in: str):
|
||||
mac = "94:b9:7e:fb:57:1a"
|
||||
polling_interval_secons = 1
|
||||
polling_headers = {
|
||||
'accept' : 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
stop = False
|
||||
state = False
|
||||
while (not stop):
|
||||
sleep(polling_interval_secons)
|
||||
data = {
|
||||
'bluetooth_mac': mac,
|
||||
'state': state,
|
||||
'token': token_in
|
||||
}
|
||||
data_dict = poll(poll_url, data, polling_headers)
|
||||
if not data_dict: continue
|
||||
if data_dict['open_command']: state = True
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
emulate("https://ibs.cronos.typedef.cf:4040/iotdevice/door/status",
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJibHVldG9vdGhfbWFjIjoiOTQ6Yjk6N2U6ZmI6NTc6MWEifQ.oRbL0U70g8HGkKIOnwkesDiB40VWTPmwIWiysvP-hXA")
|
31
sql_app/tools/ibs.service
Normal file
31
sql_app/tools/ibs.service
Normal file
@ -0,0 +1,31 @@
|
||||
# This is templte to use for python venv applications
|
||||
# from https://broplanner.com/wp-content/webpc-passthru.php?src=https://broplanner.com/wp-content/uploads/2022/01/Screenshot-2022-01-25-224223-1536x237.png&nocache=1
|
||||
[Unit]
|
||||
After = network.target
|
||||
|
||||
[Service]
|
||||
User=ibs
|
||||
Group=ibs
|
||||
WorkingDirectory=/srv/ibs/ibs
|
||||
ExecStart=/srv/ibs/ibs/run-tls
|
||||
|
||||
Restart=on-failure
|
||||
RestartSec=15
|
||||
|
||||
# Security
|
||||
ReadWritePaths=/srv/ibs/ibs
|
||||
PrivateDevices=yes
|
||||
PrivateMounts=yes
|
||||
PrivateTmp=yes
|
||||
PrivateUsers=yes
|
||||
ProtectClock=yes
|
||||
ProtectControlGroups=yes
|
||||
ProtectHome=yes
|
||||
ProtectKernelLogs=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectKernelTunables=yes
|
||||
ProtectProc=yes
|
||||
ProtectHostname=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -1,3 +1,5 @@
|
||||
# May 2022
|
||||
# Hesham T. Banafa <hishaminv@gmail.com>
|
||||
|
||||
from .database import SessionLocal
|
||||
|
||||
@ -7,3 +9,8 @@ def get_db():
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
EMERG_TEMP = 50
|
||||
EMERG_SMOKE = 1000
|
||||
EMERG_OPEN_TIME_SEC = 500
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user