just before mailing

master
Kerem Yollu 10 months ago
parent 996b2cdfcd
commit 9e30d68422

@ -0,0 +1,5 @@
[
{
"test": "data"
}
]

@ -1 +0,0 @@
,key,devbian,13.08.2024 18:20,file:///home/key/.config/libreoffice/4;

@ -1,2 +1,2 @@
name,device_id,serial_no,imsi,iccid,ip,port,user_id,owner_id,manufacturer_id,status_id,type_id,area_id,company_id name,device_id,serial_no,imsi,iccid,ip,port,device_user_id,device_owner_id,company_manufacturer_id,status_id,type_id,area_id,company_owner_id
miniUni,24070580,24070576,901405710203483,898822800001074,10.128.24.42,50000,1,1,1,1,1,1,3 miniUni,24070580,24070576,901405710203483,898822800001074,10.128.24.42,50000,1,1,1,1,1,1,3

1 name device_id serial_no imsi iccid ip port user_id device_user_id owner_id device_owner_id manufacturer_id company_manufacturer_id status_id type_id area_id company_id company_owner_id
2 miniUni 24070580 24070576 901405710203483 898822800001074 10.128.24.42 50000 1 1 1 1 1 1 1 1 1 3 3

Binary file not shown.

@ -30,6 +30,10 @@ class Companies(db.Model):
# Many To one # Many To one
notes = db.relationship('Notes', backref='company_notes', lazy='dynamic') notes = db.relationship('Notes', backref='company_notes', lazy='dynamic')
# Relationships to Device
manufactured_devices = db.relationship("nbiotDevice", foreign_keys="nbiotDevice.company_manufacturer_id", back_populates="company_manufacturer")
owned_devices = db.relationship("nbiotDevice", foreign_keys="nbiotDevice.company_owner_id", back_populates="company_owner")
class Company_types(db.Model): class Company_types(db.Model):
__tablename__ = 'company_types' __tablename__ = 'company_types'

@ -23,7 +23,7 @@ class updateNbioDeviceUpdateForm(FlaskForm): # Defines the form class to be use
area_id = SelectField('Area', validators=[DataRequired()]) area_id = SelectField('Area', validators=[DataRequired()])
manufacturer_id = SelectField('Manufacturer', validators=[DataRequired()]) manufacturer_id = SelectField('Manufacturer', validators=[DataRequired()])
company_id = SelectField('Managed By', validators=[DataRequired()]) company_id = SelectField('Managed By', validators=[DataRequired()])
picture = FileField('Update Sensor Picture', validators=[FileAllowed(['jpg', 'png'])])
submit = SubmitField(f'Update') submit = SubmitField(f'Update')
def __init__(self, current_device_id, *args, **kwargs): def __init__(self, current_device_id, *args, **kwargs):

@ -19,20 +19,28 @@ class nbiotDevice(db.Model):
created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
updated = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) updated = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
owner_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
status_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceStatus.id'), nullable=False) status_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceStatus.id'), nullable=False)
type_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceType.id'), nullable=False) type_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceType.id'), nullable=False)
area_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceArea.id'), nullable=False) area_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceArea.id'), nullable=False)
manufacturer_id = db.Column(db.Integer, db.ForeignKey('companies.id'), nullable=False)
company_id = db.Column(db.Integer, db.ForeignKey('companies.id'), nullable=False)
# Foreign Keys
company_manufacturer_id = db.Column(db.Integer, db.ForeignKey('companies.id'))
company_owner_id = db.Column(db.Integer, db.ForeignKey('companies.id'))
device_user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
device_owner_id = db.Column(db.Integer, db.ForeignKey('users.id'))
# Relationships
company_manufacturer = db.relationship("Companies", foreign_keys=[company_manufacturer_id], back_populates="manufactured_devices")
company_owner = db.relationship("Companies", foreign_keys=[company_owner_id], back_populates="owned_devices")
device_user = db.relationship("Users", foreign_keys=[device_user_id], back_populates="used_devices")
device_owner = db.relationship("Users", foreign_keys=[device_owner_id], back_populates="owned_devices")
class nbiotDeviceStatus(db.Model): class nbiotDeviceStatus(db.Model):
__tablename__ = 'nbiotDeviceStatus' __tablename__ = 'nbiotDeviceStatus'
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False) name = db.Column(db.String(50), nullable=False)
description = db.Column(db.String(300), nullable=False) description = db.Column(db.String(300), nullable=False)
devices = db.relationship('nbiotDevice', backref='status', lazy='dynamic')
class nbiotDeviceType(db.Model): class nbiotDeviceType(db.Model):
@ -40,6 +48,7 @@ class nbiotDeviceType(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False) name = db.Column(db.String(50), nullable=False)
description = db.Column(db.String(300), nullable=False) description = db.Column(db.String(300), nullable=False)
devices = db.relationship('nbiotDevice', backref='type', lazy='dynamic')
class nbiotDeviceArea(db.Model): class nbiotDeviceArea(db.Model):
@ -47,6 +56,7 @@ class nbiotDeviceArea(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False) name = db.Column(db.String(50), nullable=False)
description = db.Column(db.String(300), nullable=False) description = db.Column(db.String(300), nullable=False)
devices = db.relationship('nbiotDevice', backref='area', lazy='dynamic')
class waterDetector(db.Model): class waterDetector(db.Model):

@ -1,4 +1,4 @@
from flask import render_template, Blueprint, request, flash, redirect, url_for from flask import render_template, Blueprint, request, flash, redirect, url_for, jsonify
import minibase.theme as theme import minibase.theme as theme
from minibase.blueprints.sensor.models import nbiotDevice from minibase.blueprints.sensor.models import nbiotDevice
import minibase.blueprints.sensor.utils as sensorUtils import minibase.blueprints.sensor.utils as sensorUtils
@ -6,36 +6,52 @@ from minibase.blueprints.sensor.forms import updateNbioDeviceUpdateForm, updateN
import minibase.blueprints.database.utils as dbUtils import minibase.blueprints.database.utils as dbUtils
import minibase.blueprints.company.utils as companyUtils import minibase.blueprints.company.utils as companyUtils
import minibase.blueprints.user.utils as userUtils import minibase.blueprints.user.utils as userUtils
import minibase.blueprints.main.utils as mainUtils
from minibase.app import db from minibase.app import db
import json import json
import os import os
# TODO:
sensor = Blueprint('sensor', __name__, template_folder='templates') sensor = Blueprint('sensor', __name__, template_folder='templates')
DATA_FILE = 'data.json' DATA_FILE = 'data.json'
sensor.route('/callback', methods=['POST']) @sensor.route('/callback', methods=['POST'])
def callback(): def callback():
data = request.json data = request.json
if not data: if not data:
return jsonify({"error": "Invalid data"}), 400 return ({"error": "Invalid data"}), 400
# Read existing data # Access each element from the data
if os.path.exists(DATA_FILE): customer_id = data[0].get("customerId")
with open(DATA_FILE, 'r') as f: rcv_time = data[0].get("rcvTime")
stored_data = json.load(f) src_imsi = data[0].get("srcImsi")
else: src_ip = data[0].get("srcIP")
stored_data = [] src_port = data[0].get("srcPort")
payload = data[0].get("payload")
# Append new data
stored_data.append(data) # Print the elements to the console (for debugging)
#print(f"Customer ID: {customer_id}")
# Write data back to file #print(f"Receive Time: {rcv_time}")
with open(DATA_FILE, 'w') as f: #print(f"Source IMSI: {src_imsi}")
json.dump(stored_data, f, indent=4) #print(f"Source IP: {src_ip}")
#print(f"Source Port: {src_port}")
return 'Callback received', 200 #print(f"Payload: {payload}")
response_data = {
"customerId": customer_id,
"rcvTime": rcv_time,
"srcImsi": src_imsi,
"srcIP": src_ip,
"srcPort": src_port,
"payload": payload
}
sensorUtils.decode_payload(payload)
return jsonify(response_data), 200
#return 'data recieved', 200
@sensor.route('/data', methods=['GET']) @sensor.route('/data', methods=['GET'])
@ -61,14 +77,17 @@ def edit(deviceId):
if deviceId: if deviceId:
device = nbiotDevice.query.get_or_404(deviceId) device = nbiotDevice.query.get_or_404(deviceId)
form = updateNbioDeviceUpdateForm(current_device_id=device.id) form = updateNbioDeviceUpdateForm(current_device_id=device.id)
form.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.user_id)] form.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.device_user_id)]
form.owner_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.user_id)] form.owner_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.device_owner_id)]
form.manufacturer_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.manufacturer_id)] form.manufacturer_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_manufacturer_id)]
form.company_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_id)] form.company_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_owner_id)]
form.status_id.choices = [(row.id, row.name) for row in sensorUtils.queryStatusNamesWithDefault(device.status_id)] form.status_id.choices = [(row.id, row.name) for row in sensorUtils.queryStatusNamesWithDefault(device.status_id)]
form.type_id.choices = [(row.id, row.name) for row in sensorUtils.queryTypeNamesWithDefault(device.type_id)] form.type_id.choices = [(row.id, row.name) for row in sensorUtils.queryTypeNamesWithDefault(device.type_id)]
form.area_id.choices = [(row.id, row.name) for row in sensorUtils.queryAreaNamesWithDefault(device.area_id)] form.area_id.choices = [(row.id, row.name) for row in sensorUtils.queryAreaNamesWithDefault(device.area_id)]
if form.validate_on_submit(): if form.validate_on_submit():
if form.picture.data:
picture_file = mainUtils.save_picture(form.picture.data)
device.image_file = picture_file
device.name=form.name.data device.name=form.name.data
device.serial_no = form.serial_no.data device.serial_no = form.serial_no.data
device.device_id=form.device_id.data device.device_id=form.device_id.data
@ -79,13 +98,13 @@ def edit(deviceId):
device.registration_date=form.registration_date.data device.registration_date=form.registration_date.data
device.activation_date=form.activation_date.data device.activation_date=form.activation_date.data
device.deactivation_date=form.deactivation_date.data device.deactivation_date=form.deactivation_date.data
device.owner_id=form.owner_id.data device.device_owner_id=form.owner_id.data
device.user_id=form.user_id.data device.device_user_id=form.user_id.data
device.status_id=form.status_id.data device.status_id=form.status_id.data
device.type_id=form.type_id.data device.type_id=form.type_id.data
device.area_id=form.area_id.data device.area_id=form.area_id.data
device.manufacturer_id = form.manufacturer_id.data device.company_manufacturer_id = form.manufacturer_id.data
device.company_id = form.company_id.data device.company_owner_id = form.company_id.data
db.session.commit() db.session.commit()
flash('Device has been successfully updated', 'success') flash('Device has been successfully updated', 'success')
return redirect(url_for('sensor.edit', deviceId=deviceId)) return redirect(url_for('sensor.edit', deviceId=deviceId))
@ -100,9 +119,17 @@ def edit(deviceId):
form.registration_date.data = device.registration_date form.registration_date.data = device.registration_date
form.activation_date.data = device.activation_date form.activation_date.data = device.activation_date
form.deactivation_date.data = device.deactivation_date form.deactivation_date.data = device.deactivation_date
form.user_id.data = device.device_user.username
form.owner_id.data = device.device_owner.username
form.manufacturer_id.data = device.company_manufacturer.name
form.company_id.data = device.company_owner.name
form.status_id.data = device.status.name
form.type_id.data = device.type.name
form.area_id.data = device.area.name
image_file = url_for('static', filename='pics/' + sensorUtils.queryImageById(deviceId))
return render_template('sensor/account.html', return render_template('sensor/account.html',
theme=theme, theme=theme,
image_file=image_file,
form=form) form=form)
else: else:
flash('You need to select a Device id', 'alarm') flash('You need to select a Device id', 'alarm')

@ -5,21 +5,24 @@
<div class="row"> <div class="row">
<div class="col-md-3 border-right"> <div class="col-md-3 border-right">
<div class="d-flex flex-column align-items-center text-center p-3 py-5"> <div class="d-flex flex-column align-items-center text-center p-3 py-5">
<h2 class="account-heading" style="color: {{ theme.orange }};">{{ current_user.username }}</h2> <img class="rounded-circle mt-4 border-info" width="150px" src="{{ image_file }}">
<h5 class="account-heading" style="color: {{ theme.light_blue }};">{{ current_user.email_account }}</h5> <br>
<h2 class="account-heading" style="color: {{ theme.orange }};">{{ form.name.data }}</h2>
<h3 class="account-heading" style="color: {{ theme.orange }};">{{ form.company_id.data }}</h2>
<h5 class="account-heading" style="color: {{ theme.light_blue }};">{{ form.owner_id.data }}</h5>
<div class="p-3 py-5">
<h4 class="account-heading" style="color: {{ theme.yellow }};">{{ form.status_id.data }}</h4>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-5 border-right"> <div class="col-md-4">
<div class="p-3 py-5"> <div class="p-3 py-4">
{% include 'form.html' %} {% include 'form.html' %}
</div> </div>
</div> </div>
<div class="col-md-4">
<div class="col-md-4 rounded"> <div class="p-3 py-4">
<div class="p-3 py-5">
{{ info }}
</div> </div>
</div> </div>
</div> </div>

@ -1,8 +1,11 @@
from minibase.blueprints.sensor.models import nbiotDevice, nbiotDeviceStatus, nbiotDeviceType, nbiotDeviceArea from minibase.blueprints.sensor.models import nbiotDevice, nbiotDeviceStatus, nbiotDeviceType, nbiotDeviceArea
import minibase.blueprints.database.utils as dbUtils import minibase.blueprints.database.utils as dbUtils
from sqlalchemy import case from sqlalchemy import case
import base64
def queryImageById(id):
selected = nbiotDevice.query.filter_by(id=id).first()
return selected.image_file
def queryById(id): def queryById(id):
return nbiotDevice.query.filter_by(id=id).first() return nbiotDevice.query.filter_by(id=id).first()
@ -21,3 +24,80 @@ def queryTypeNamesWithDefault(defId):
def queryAreaNamesWithDefault(defId): def queryAreaNamesWithDefault(defId):
choices = dbUtils.queryNameWithDefaultId(nbiotDeviceArea, defId) choices = dbUtils.queryNameWithDefaultId(nbiotDeviceArea, defId)
return choices return choices
def decode_payload(payload_string):
# Ensure the payload is the correct length
payload = base64.b64decode(payload_string).hex()
if len(payload) != 16:
print(f"Payload length must be 16 characters (8 bytes) current is : {len(payload)}")
raise ValueError("Payload length must be 16 characters (8 bytes)")
# Split the payload into bytes
msb_id = payload[0:2]
second_byte_id = payload[2:4]
third_byte_id = payload[4:6]
lsb_id = payload[6:8]
battery_voltage = payload[8:10]
signal_quality = payload[10:12]
input_byte = payload[12:14]
alarm_byte = payload[14:16]
# Convert hex strings to integers
msb_id = int(msb_id, 16)
second_byte_id = int(second_byte_id, 16)
third_byte_id = int(third_byte_id, 16)
lsb_id = int(lsb_id, 16)
battery_voltage = int(battery_voltage, 16)
signal_quality = int(signal_quality, 16)
input_byte = int(input_byte, 16)
alarm_byte = int(alarm_byte, 16)
# Calculate voltage in mV
voltage_mv = battery_voltage * 30
# Determine signal quality or RSSI
if signal_quality == 99:
signal_str = "Signal quality not retrieved"
rssi = None
else:
rssi = signal_quality - 110
signal_str = f"Signal Quality: {signal_quality} (RSSI: {rssi} dB)"
# Decode pin status
pins_status = {
'IN1': (input_byte & 0b00001) != 0,
'IN2': (input_byte & 0b00010) != 0,
'IN3': (input_byte & 0b00100) != 0,
'IN4': (input_byte & 0b01000) != 0,
'IN5': (input_byte & 0b10000) != 0,
}
# Decode alarm status
alarms_status = {
'IN1': (alarm_byte & 0b00001) != 0,
'IN2': (alarm_byte & 0b00010) != 0,
'IN3': (alarm_byte & 0b00100) != 0,
'IN4': (alarm_byte & 0b01000) != 0,
'IN5': (alarm_byte & 0b10000) != 0,
}
# Print decoded values
uid = str(f'{msb_id:02x}{second_byte_id:02x}{third_byte_id:02x}{lsb_id:02x}')
print(f"UID: {uid}")
print(f"Battery Voltage: {battery_voltage:#04x} (Voltage: {voltage_mv/1000} V)")
for pin in range(1, 6):
pin_status = 'High' if pins_status[f'IN{pin}'] else 'Low'
alarm_status = 'Alarm' if alarms_status[f'IN{pin}'] else 'No Alarm'
print(f"Pin IN{pin} Status: {pin_status}, {alarm_status}")
print(signal_str)
# Return decoded values in a dictionary
return {
"uid" : uid,
"battery_voltage": voltage_mv,
"signal_quality": signal_quality,
"rssi": rssi,
"pins_status": pins_status,
"alarms_status": alarms_status
}

@ -3,7 +3,7 @@ from flask_wtf.file import FileField, FileAllowed
from wtforms import StringField, PasswordField, SubmitField, BooleanField, URLField from wtforms import StringField, PasswordField, SubmitField, BooleanField, URLField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from flask_login import current_user from flask_login import current_user
from minibase.blueprints.user.models import Users from minibase.blueprints.user.models import Users, User_Roles
class registrationForm(FlaskForm): # Defines the form class to be used for the user registretion class registrationForm(FlaskForm): # Defines the form class to be used for the user registretion
@ -78,4 +78,3 @@ class updateRoleForm(FlaskForm):
role = StringField('Role', validators=[DataRequired(), Length(min=4, max=20)]) role = StringField('Role', validators=[DataRequired(), Length(min=4, max=20)])
description = StringField('Description', validators=[DataRequired(), Length(min=4, max=200)]) description = StringField('Description', validators=[DataRequired(), Length(min=4, max=200)])
submit = SubmitField() submit = SubmitField()

@ -24,7 +24,6 @@ class Users(db.Model, UserMixin):
last_update_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) last_update_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relations One To Many # Relations One To Many
notes = db.relationship('Notes', backref='author', lazy='dynamic') notes = db.relationship('Notes', backref='author', lazy='dynamic')
todos = db.relationship('Todos', backref='author', lazy='dynamic') todos = db.relationship('Todos', backref='author', lazy='dynamic')
@ -35,7 +34,9 @@ class Users(db.Model, UserMixin):
role_id = db.Column(db.Integer, db.ForeignKey('user_roles.id'), nullable=False, default=2) role_id = db.Column(db.Integer, db.ForeignKey('user_roles.id'), nullable=False, default=2)
role = db.relationship('User_Roles', backref=db.backref('users', lazy='dynamic')) role = db.relationship('User_Roles', backref=db.backref('users', lazy='dynamic'))
# Relationships to Device
used_devices = db.relationship("nbiotDevice", foreign_keys="nbiotDevice.device_user_id", back_populates="device_user")
owned_devices = db.relationship("nbiotDevice", foreign_keys="nbiotDevice.device_owner_id", back_populates="device_owner")
def get_reset_token(self, expires_sec=1800): def get_reset_token(self, expires_sec=1800):
s = Serializer(current_app.config['SECRET_KEY']) s = Serializer(current_app.config['SECRET_KEY'])
@ -50,9 +51,9 @@ class Users(db.Model, UserMixin):
return 0 return 0
return Users.query.get(user_id) return Users.query.get(user_id)
class User_Roles(db.Model): class User_Roles(db.Model):
__tablename__ = 'user_roles' __tablename__ = 'user_roles'
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), unique=True, nullable=False) name = db.Column(db.String(20), unique=True, nullable=False)
description = db.Column(db.String(200), unique=False, nullable=True) description = db.Column(db.String(200), unique=False, nullable=True)

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 KiB

@ -83,7 +83,7 @@ class menu:
{"menuName":"Sensor", {"menuName":"Sensor",
"sublinks": [ "sublinks": [
{"text": "List", "url": "main.index"}, {"text": "List", "url": "sensor.list"},
{"decoration": "line"}, {"decoration": "line"},
{"text": "Add", "url": "main.index"}, {"text": "Add", "url": "main.index"},
{"decoration": "line"}, {"decoration": "line"},

Loading…
Cancel
Save