Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aa9d270039 | |||
| 32bc481a91 | |||
| 0e30bd1263 | |||
| dda51889dc | |||
| 0c811f529b |
@@ -20,29 +20,44 @@ class Collection(Base):
|
||||
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
|
||||
|
||||
@classmethod
|
||||
def create_collection(cls, collection_name, parent):
|
||||
def create_collection(cls, collection_name, parent, duplicate=False):
|
||||
with Session() as session:
|
||||
name = cls.check_name_duplicate(collection_name, parent, 0)
|
||||
collection = Collection(
|
||||
name = name,
|
||||
parent = parent,
|
||||
type= "folder",
|
||||
)
|
||||
session.add(collection)
|
||||
session.commit()
|
||||
print('a', collection.id)
|
||||
return collection
|
||||
name = cls.check_name_duplicate(collection_name, parent, 0, duplicate=duplicate)
|
||||
if name == None:
|
||||
return session.query(Collection).filter(Collection.name == collection_name, Collection.parent == parent).first()
|
||||
else:
|
||||
collection = Collection(
|
||||
name = name,
|
||||
parent = parent,
|
||||
type= "folder",
|
||||
)
|
||||
session.add(collection)
|
||||
session.commit()
|
||||
session.refresh(collection)
|
||||
return collection
|
||||
|
||||
@classmethod
|
||||
def check_name_duplicate(cls, collection_name, parent, n):
|
||||
with Session() as session:
|
||||
result = session.query(Collection).filter(Collection.name == cls.generate_name(collection_name, n), Collection.parent == parent).first()
|
||||
def check_name_duplicate(cls, collection_name, parent, n, _session = None, duplicate=False):
|
||||
if _session == None:
|
||||
with Session() as session:
|
||||
result = session.query(Collection).filter(Collection.name == cls.generate_name(collection_name, n), Collection.parent == parent).first()
|
||||
if result is None:
|
||||
return cls.generate_name(collection_name, n)
|
||||
else:
|
||||
if duplicate == True:
|
||||
return None
|
||||
else:
|
||||
new_num = n + 1
|
||||
# new_name = f"{collection_name}({new_num})"
|
||||
return cls.check_name_duplicate(collection_name, parent, new_num, session)
|
||||
else:
|
||||
result = _session.query(Collection).filter(Collection.name == cls.generate_name(collection_name, n), Collection.parent == parent).first()
|
||||
if result is None:
|
||||
return cls.generate_name(collection_name, n)
|
||||
else:
|
||||
new_num = n + 1
|
||||
# new_name = f"{collection_name}({new_num})"
|
||||
return cls.check_name_duplicate(collection_name, parent, new_num)
|
||||
return cls.check_name_duplicate(collection_name, parent, new_num, _session)
|
||||
|
||||
@classmethod
|
||||
def generate_name(cls, collection_name, n):
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
from sqlalchemy import Table, Column, String, MetaData, ForeignKey, JSON
|
||||
from sqlalchemy.sql import select, func
|
||||
from sqlalchemy.types import Integer, BigInteger, String, Boolean, TIMESTAMP, Numeric
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
|
||||
from .base import Base, Session
|
||||
|
||||
class RecordingDataMeta(Base):
|
||||
__tablename__ = "recording_data_metas"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
path = Column(String(255))
|
||||
name = Column(String(255))
|
||||
parent = Column(JSONB)
|
||||
size = Column(String(255))
|
||||
time_duration = (String(255))
|
||||
raw_data = Column(JSONB)
|
||||
project = Column(Integer)
|
||||
deleted = Column(Boolean, default = False)
|
||||
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
|
||||
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
|
||||
|
||||
# def __repr__(self):
|
||||
# return f"User(id={self.id!r}, name={self.name!r}, fullname={self.task!r})"
|
||||
@@ -0,0 +1,88 @@
|
||||
from sqlalchemy import Table, Column, String, MetaData, ForeignKey, JSON
|
||||
from sqlalchemy.sql import select, func
|
||||
from sqlalchemy.types import Integer, BigInteger, String, Boolean, TIMESTAMP, Numeric, Text
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
from biopro.db.base import Session
|
||||
|
||||
from .base import Base
|
||||
|
||||
# build a model class with a specific table name
|
||||
def get_raw_model(channel):
|
||||
tablename = str(channel) + '_recording_data_raws' # dynamic table name
|
||||
class_name = 'RECORDING_DATA_RAWS' # dynamic class name
|
||||
print('get_raw_model', tablename)
|
||||
|
||||
for mapper in Base.registry.mappers:
|
||||
cls = mapper.class_
|
||||
classname = cls.__name__
|
||||
tblname = cls.__tablename__
|
||||
print(cls, classname, tblname)
|
||||
if (classname == class_name):
|
||||
if tblname == tablename:
|
||||
return cls
|
||||
|
||||
Model = type(class_name, (RECORDING_DATA_RAWS,), {
|
||||
'__tablename__': tablename
|
||||
})
|
||||
return Model
|
||||
|
||||
|
||||
class RECORDING_DATA_RAWS(Base):
|
||||
__abstract__ = True
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String(255))
|
||||
parent = Column(Integer)
|
||||
size = Column(String(255))
|
||||
path = Column(JSONB)
|
||||
uuid = Column(String(255))
|
||||
serial_number = Column(String(255))
|
||||
data_format = Column(String(255))
|
||||
channel = Column(Integer)
|
||||
start_time = Column(String(255))
|
||||
end_time = Column(String(255))
|
||||
data = Column(Text)
|
||||
compressed = Column(Boolean)
|
||||
deleted = Column(Boolean)
|
||||
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
|
||||
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
|
||||
|
||||
# @classmethod
|
||||
# def create_subject_data(cls, subject_id, project, meta, data):
|
||||
# with Session() as session:
|
||||
# subject = Subject(
|
||||
# subject_id = subject_id,
|
||||
# project = project,
|
||||
# meta= meta,
|
||||
# data = data
|
||||
# )
|
||||
# session.add(subject)
|
||||
# session.commit()
|
||||
# return subject
|
||||
|
||||
# @classmethod
|
||||
# def check_name_duplicate(cls, collection_name, parent, n):
|
||||
# with Session() as session:
|
||||
# result = session.query(Collection).filter(Collection.name == cls.generate_name(collection_name, n), Collection.parent == parent).first()
|
||||
# if result is None:
|
||||
# return cls.generate_name(collection_name, n)
|
||||
# else:
|
||||
# new_num = n + 1
|
||||
# # new_name = f"{collection_name}({new_num})"
|
||||
# return cls.check_name_duplicate(collection_name, parent, new_num)
|
||||
|
||||
# @classmethod
|
||||
# def generate_name(cls, collection_name, n):
|
||||
# if n==0:
|
||||
# return collection_name
|
||||
# else:
|
||||
# return f"{collection_name}({n})"
|
||||
|
||||
# @classmethod
|
||||
# def find_data(cls, id):
|
||||
# with Session() as session:
|
||||
|
||||
# result = session.query(RECORDING_DATA_RAWS).first()
|
||||
# return result
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
from sqlalchemy import Table, Column, String, MetaData, ForeignKey, JSON
|
||||
from sqlalchemy.sql import select, func
|
||||
from sqlalchemy.types import Integer, BigInteger, String, Boolean, TIMESTAMP, Numeric
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
from biopro.db.base import Session
|
||||
|
||||
from .base import Base
|
||||
|
||||
class SubjectData(Base):
|
||||
__tablename__ = "subject_datas"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
subject_id = Column(Integer)
|
||||
mode = Column(JSONB)
|
||||
data = Column(JSONB)
|
||||
user_auth = Column(JSONB)
|
||||
meta = Column(String(255))
|
||||
project = Column(String(255))
|
||||
deleted = Column(Boolean)
|
||||
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
|
||||
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
|
||||
|
||||
@classmethod
|
||||
def create_subject_data(cls, subject_id, project, meta, data):
|
||||
with Session() as session:
|
||||
subject = SubjectData(
|
||||
subject_id = subject_id,
|
||||
project = project,
|
||||
meta= meta,
|
||||
data = data
|
||||
)
|
||||
session.add(subject)
|
||||
session.commit()
|
||||
return subject
|
||||
|
||||
# @classmethod
|
||||
# def check_name_duplicate(cls, collection_name, parent, n):
|
||||
# with Session() as session:
|
||||
# result = session.query(Collection).filter(Collection.name == cls.generate_name(collection_name, n), Collection.parent == parent).first()
|
||||
# if result is None:
|
||||
# return cls.generate_name(collection_name, n)
|
||||
# else:
|
||||
# new_num = n + 1
|
||||
# # new_name = f"{collection_name}({new_num})"
|
||||
# return cls.check_name_duplicate(collection_name, parent, new_num)
|
||||
|
||||
# @classmethod
|
||||
# def generate_name(cls, collection_name, n):
|
||||
# if n==0:
|
||||
# return collection_name
|
||||
# else:
|
||||
# return f"{collection_name}({n})"
|
||||
|
||||
# @classmethod
|
||||
# def find_collection(cls, collection_name, parent):
|
||||
# with Session() as session:
|
||||
# result = session.query(Collection).filter(Collection.name == collection_name, Collection.parent == parent).first()
|
||||
# return result
|
||||
|
||||
|
||||
@@ -1292,6 +1292,9 @@ class CompletedDevice(Device):
|
||||
|
||||
def central_version_get(self) -> Optional[list]:
|
||||
return self._device.central_version_get()
|
||||
|
||||
def save_data_to_subject(self, project, meta, device, subject_id):
|
||||
self._master._handler.save_data_to_subject(project, meta, device, subject_id)
|
||||
|
||||
# utility method
|
||||
|
||||
|
||||
@@ -49,6 +49,9 @@ class Project(threading.Thread):
|
||||
|
||||
self._count = 1 #流水號
|
||||
|
||||
self._project_meta_id = -1
|
||||
self._subject = []
|
||||
|
||||
self.log_verbose = log_verbose
|
||||
self._logger = logging.getLogger('project')
|
||||
self._logger.setLevel('DEBUG')
|
||||
@@ -69,7 +72,10 @@ class Project(threading.Thread):
|
||||
collection = Collection.find_collection(default_name, default_parent)
|
||||
parent = {"folder": [collection.id]}
|
||||
# create project folder
|
||||
collection = Collection.create_collection(self.name, parent)
|
||||
folder_name_duplicate = False
|
||||
if len(self._subject) > 0:
|
||||
folder_name_duplicate = True
|
||||
collection = Collection.create_collection(self.name, parent, folder_name_duplicate)
|
||||
self.setup_collection(collection)
|
||||
|
||||
def setup_project(self, project):
|
||||
@@ -101,6 +107,22 @@ class Project(threading.Thread):
|
||||
@id.setter
|
||||
def id(self, new_id):
|
||||
self._id = new_id
|
||||
|
||||
@property
|
||||
def project_meta_id(self) -> int:
|
||||
return self._project_meta_id
|
||||
|
||||
@project_meta_id.setter
|
||||
def project_meta_id(self, new_project_meta_id):
|
||||
self._project_meta_id = new_project_meta_id
|
||||
|
||||
@property
|
||||
def subject(self) -> object:
|
||||
return self._subject
|
||||
|
||||
@subject.setter
|
||||
def subject(self, new_subject):
|
||||
self._subject = new_subject
|
||||
|
||||
@property
|
||||
def uuid(self) -> str:
|
||||
@@ -278,6 +300,9 @@ class Project(threading.Thread):
|
||||
args = list(map(lambda arg: task_info[arg], instruction['arguments']))
|
||||
target=getattr(device, instruction['method'])(*args)
|
||||
print('instruction 2', device, instruction, datetime.now())
|
||||
if (action.type == 'stop'):
|
||||
if (len(self._subject) > 0):
|
||||
target=getattr(device, "save_data_to_subject")(self.id, self.project_meta_id, device, self._subject[0])
|
||||
if action.type == 'start':
|
||||
self._count += 1
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ class TaskManager():
|
||||
for index, task in enumerate(self._task_list):
|
||||
if self.check_task_in_cycle(index) == True:
|
||||
if task.type == '':
|
||||
collection = Collection.create_collection(task.name, {"folder": [parent.id]})
|
||||
collection = Collection.create_collection(task.name, {"folder": [parent.id]}, False)
|
||||
task.parent = {"folder": [collection.id]}
|
||||
else:
|
||||
task.parent = {"folder": [parent.id]}
|
||||
@@ -35,8 +35,11 @@ from biopro.project.project_manager import ProjectManager
|
||||
from biopro.db.base import Base, Session, engine
|
||||
from biopro.db.project_report import ProjectReport
|
||||
from biopro.db.project_meta import MetaProjectInfo
|
||||
from biopro.db.device import Device
|
||||
|
||||
# from biopro.db.device import Device
|
||||
from biopro.db.recording_data import get_raw_model
|
||||
from biopro.db.subject_data import SubjectData
|
||||
from biopro.db.meta import RecordingDataMeta
|
||||
import random
|
||||
|
||||
_RUNTIME_COMPILE = False
|
||||
|
||||
@@ -329,6 +332,18 @@ class ControlServer(SocketServer, ControlServerAPI):
|
||||
finally:
|
||||
self.led_thread.set_state(LED.AVAILABLE)
|
||||
|
||||
# version_info = [0, 2, 1, 7, 23, 2]
|
||||
# serial_number = DeviceSerialNumber(version_info[0],
|
||||
# version_info[1],
|
||||
# version_info[2],
|
||||
# version_info[3],
|
||||
# version_info[4],
|
||||
# version_info[5])
|
||||
# response = DeviceResponseInfo('Elite-EDC', serial_number, (164, 218, 50, 212, 231, 12), addr_type=0)
|
||||
# print('setup done', response)
|
||||
# ret = self.device_manager.connect(response)
|
||||
# print('ret', ret)
|
||||
|
||||
def _setup_get_available_channel(self) -> Optional[List[int]]:
|
||||
client = self.data_server.client()
|
||||
|
||||
@@ -558,8 +573,15 @@ class ControlServer(SocketServer, ControlServerAPI):
|
||||
response = content
|
||||
else:
|
||||
response = to_device_info(content)
|
||||
|
||||
try:
|
||||
# version_info = [0, 2, 1, 7, 23, 2]
|
||||
# serial_number = DeviceSerialNumber(version_info[0],
|
||||
# version_info[1],
|
||||
# version_info[2],
|
||||
# version_info[3],
|
||||
# version_info[4],
|
||||
# version_info[5])
|
||||
# response = DeviceResponseInfo('Elite-EDC', serial_number, (164, 218, 50, 212, 231, 12))
|
||||
ret = self.device_manager.connect(response)
|
||||
except DeviceInstructionError as e:
|
||||
'''when device reset fail error'''
|
||||
@@ -1107,7 +1129,7 @@ class ControlServer(SocketServer, ControlServerAPI):
|
||||
|
||||
client = self.data_server.client()
|
||||
project = None
|
||||
project_meta_id = None
|
||||
_project_meta_id = None
|
||||
if client is not None:
|
||||
info = self.file_manager.use(device)
|
||||
|
||||
@@ -1121,10 +1143,12 @@ class ControlServer(SocketServer, ControlServerAPI):
|
||||
|
||||
if device.occupied_by_project != None:
|
||||
project = self.project_manager.get(device.occupied_by_project).info_pass_data_server()
|
||||
project_meta_id = MetaProjectInfo.create_project_meta(project)
|
||||
_project_meta_id = MetaProjectInfo.create_project_meta(project)
|
||||
new_project = self.project_manager.get(device.occupied_by_project)
|
||||
new_project.project_meta_id = _project_meta_id
|
||||
|
||||
with client:
|
||||
client.update_device_configuration(device, info.meta_file, value, project_meta_id)
|
||||
client.update_device_configuration(device, info.meta_file, value, _project_meta_id)
|
||||
|
||||
def _device_set_disable_cache(self, device: CompletedDevice, disable):
|
||||
if disable:
|
||||
@@ -1354,6 +1378,57 @@ class ControlServer(SocketServer, ControlServerAPI):
|
||||
} for pkg in PipPackage.list()]
|
||||
|
||||
return ret
|
||||
|
||||
def save_data_to_subject(self, project, meta, device, subject):
|
||||
mode = device.get_parameter('MODE')
|
||||
library = device.library_name
|
||||
device = {
|
||||
"library": library,
|
||||
"mode": mode
|
||||
}
|
||||
|
||||
# "pattern": {
|
||||
# "id": number,
|
||||
# "name": string,
|
||||
# "parameter": object,
|
||||
# },
|
||||
# "data": {
|
||||
# "id": list[int],
|
||||
# "channel: list[int]
|
||||
# }
|
||||
|
||||
with Session() as session:
|
||||
meta_result = session.query(RecordingDataMeta).filter(RecordingDataMeta.project == meta).first()
|
||||
self.mqtt_thread.publish('', json.dumps({
|
||||
"pattern": {
|
||||
"id": 4,
|
||||
},
|
||||
"data": {
|
||||
"id": [meta_result.id],
|
||||
"channel": ['Time', 6]
|
||||
},
|
||||
"others": {
|
||||
"subject": subject,
|
||||
"device": device,
|
||||
"project": project,
|
||||
"project_meta": meta,
|
||||
}
|
||||
}), analysis= True)
|
||||
# result = session.query(recording_raws).order_by(recording_raws.id.desc()).first()
|
||||
# value = result.data.split(' ')[1:-1:2]
|
||||
# _value = list(map(int, value))
|
||||
# sum_value = sum(_value)
|
||||
# average_value = sum_value / len(_value)
|
||||
# subject_data = SubjectData(
|
||||
# subject_id= subject['id'],
|
||||
# project = project,
|
||||
# meta = meta,
|
||||
# mode= device,
|
||||
# data= average_value
|
||||
# )
|
||||
# # Execute the update query
|
||||
# session.add(subject_data)
|
||||
# session.commit()
|
||||
|
||||
def _hardware_send_test_hardware(self, section: Optional[str] = None) -> Dict[str, Any]:
|
||||
if section is not None:
|
||||
@@ -1398,7 +1473,6 @@ class ControlServer(SocketServer, ControlServerAPI):
|
||||
if client is not None:
|
||||
with client:
|
||||
client.show_data(device)
|
||||
|
||||
class _RandomCrashThread(ServerThread):
|
||||
def __init__(self):
|
||||
super().__init__('Crash')
|
||||
|
||||
@@ -170,9 +170,11 @@ class MqttThread(threading.Thread):
|
||||
self.sleep(3)
|
||||
self._mqtt_client_local.reconnect()
|
||||
|
||||
def publish(self, topic: str, payload: str, inter = False, qos = 2):
|
||||
def publish(self, topic: str, payload: str, inter = False, analysis=False, qos = 2):
|
||||
if inter:
|
||||
_topic = self.__controller_ID + '_user'
|
||||
elif analysis:
|
||||
_topic = self.__controller_ID + '_data_analysis/get_analysis_data'
|
||||
else:
|
||||
_topic = self.__controller_ID + '/' + topic
|
||||
if self._mqtt_client_local is not None:
|
||||
|
||||
@@ -35,4 +35,7 @@ sudo su -c "psql -d postgres -c \"ALTER TABLE devices ALTER COLUMN calibration D
|
||||
sudo su -c "psql -d postgres -c \"ALTER TABLE devices ALTER COLUMN calibration TYPE bytea USING calibration::bytea;\"" postgres
|
||||
|
||||
# add column project in recording_data_metas
|
||||
sudo su -c "psql -d postgres -c \"ALTER TABLE devices ADD COLUMN IF NOT EXISTS calibration_version Int4 DEFAULT -1;\"" postgres
|
||||
sudo su -c "psql -d postgres -c \"ALTER TABLE devices ADD COLUMN IF NOT EXISTS calibration_version Int4 DEFAULT -1;\"" postgres
|
||||
|
||||
# add column subject in project
|
||||
sudo su -c "psql -d postgres -c \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS subject JSONB;\"" postgres
|
||||
Reference in New Issue
Block a user