Commit 2d886e53 authored by Jiahang Chen's avatar Jiahang Chen
Browse files

add new features

parent 133afd68
......@@ -125,7 +125,6 @@
from ml.fml40.features.properties.values.documents.reports.soil_moisture_measurement import SoilMoistureMeasurement
from ml.mml40.features.properties.values.Displacement import Displacement
from ml.mml40.features.properties.values.GeometryProperties import GeometryProperties
from ml.mml40.features.properties.values.MaterialProperties import MaterialProperties
from ml.mml40.features.properties.values.Stretch import Stretch
......@@ -133,7 +132,6 @@
from ml.ml40.features.functionalities.accepts_reports import AcceptsReports
from ml.ml40.features.functionalities.clears_jobs import ClearsJobs
from ml.ml40.features.functionalities.functionality import Functionality
from ml.ml40.features.functionalities.get_xml_value import GetXMLValue
from ml.ml40.features.functionalities.manages_jobs import ManagesJobs
from ml.ml40.features.functionalities.plans_routes import PlansRoutes
from ml.ml40.features.functionalities.provides_map_data import ProvidesMapData
......@@ -162,7 +160,6 @@
from ml.fml40.features.functionalities.forwards import Forwards
from ml.fml40.features.functionalities.generates_afforestation_suggestions import GeneratesAfforestationSuggestions
from ml.fml40.features.functionalities.generates_felling_suggestions import GeneratesFellingSuggestions
from ml.fml40.features.functionalities.get_stanford2010_value import GetStanForD2010Value
from ml.fml40.features.functionalities.grabs import Grabs
from ml.fml40.features.functionalities.harvests import Harvests
from ml.fml40.features.functionalities.measure_wood import MeasuresWood
......@@ -254,6 +251,7 @@ def build(thing, model):
ditto_features = model.get("features", None)
if not isinstance(model, dict):
# TODO JSON Schema
APP_LOGGER.critical("model is no valid JSON")
return
roles = attributes.get("roles", [])
......@@ -353,7 +351,8 @@ def add_function_impl_obj(thing, impl_obj, feature_name, **kwargs):
def create_thing(model, grant_type="password",
secret="", username=None, password=None,
is_broker_rest=False, is_broker=False, is_repo=False, is_stanford2010=False,
stanford2010_sync_freq=None,stanford2010_path=None):
stanford2010_sync_freq=None, stanford2010_path=None, is_database=False,
database_conf=None, database_file=None):
"""
Creates and launches a thing which connects to the S3I
......@@ -398,7 +397,10 @@ def create_thing(model, grant_type="password",
is_repo=is_repo,
is_stanford2010=is_stanford2010,
stanford2010_sync_freq=stanford2010_sync_freq,
stanford2010_path=stanford2010_path
stanford2010_path=stanford2010_path,
is_database=is_database,
database_conf=database_conf,
database_file=database_file,
)
build(thing_ref, model)
......
from ml.ml40.features.functionalities.get_xml_value import GetXMLValue
class GetStanForD2010Value(GetXMLValue):
def __init__(self, name="", identifier=""):
super().__init__(
name=name,
identifier=identifier)
from ml.ml40.features.functionalities.functionality import Functionality
class GetXMLValue(Functionality):
def __init__(self, name="", identifier=""):
super().__init__(
name=name,
identifier=identifier)
def getValueByPath(self, XPath):
pass
\ No newline at end of file
......@@ -14,7 +14,16 @@ def __init__(self, name="", identifier=""):
name=name,
identifier=identifier)
def calculateDisplacement(self) -> Displacement:
def compileDisplacementWithGeometry(self, geometryType) -> Displacement:
pass
def compileDisplacementWithMaterial(self, materialType) -> Displacement:
pass
def getMaxDisplacement(self) -> Displacement:
pass
def getMinDisplacement(self) -> Displacement:
pass
def getDisplacementData(self, time) -> Displacement:
......
......@@ -14,7 +14,16 @@ def __init__(self, name="", identifier=""):
name=name,
identifier=identifier)
def calculateForce(self) -> Force:
def compileForceWithMaterial(self, materialType) -> Force:
pass
def compileForceWithGeometry(self, geometryType) -> Force:
pass
def getMaxForce(self) -> Force:
pass
def getMinForce(self) -> Force:
pass
def getForceData(self, time) -> Force:
......
......@@ -21,3 +21,8 @@ def getStretchData(self, time) -> Stretch:
def getStretchDataSeries(self, startTime, endTime):
pass
def getMaxStretch(self) -> Stretch:
pass
def getMinStretch(self) -> Stretch:
pass
......@@ -7,8 +7,6 @@ def __init__(self, name="", identifier=""):
name=name,
identifier=identifier)
self.__displacement = None
self.__max_displacement = None
self.__min_displacement = None
@property
def displacement(self):
......@@ -18,29 +16,9 @@ def displacement(self):
def displacement(self, value):
self.__displacement = value
@property
def maxDisplacement(self):
return self.__max_displacement
@maxDisplacement.setter
def maxDisplacement(self, value):
self.__max_displacement = value
@property
def minDisplacement(self):
return self.__min_displacement
@minDisplacement.setter
def minDisplacement(self, value):
self.__min_displacement = value
def to_json(self):
self.__json_out = super().to_json()
if self.displacement is not None:
self.__json_out["displacement"] = self.displacement
if self.minDisplacement is not None:
self.__json_out["minDisplacement"] = self.minDisplacement
if self.maxDisplacement is not None:
self.__json_out["maxDisplacement"] = self.maxDisplacement
return self.__json_out
\ No newline at end of file
from ml.ml40.features.properties.values.value import Value
class GeometryProperties(Value):
def __init__(self, name="", identifier=""):
super().__init__(
name=name,
identifier=identifier)
self.__geometry_type = None
self.__height = None
self.__length = None
self.__width = None
@property
def geometryType(self):
return self.__geometry_type
@geometryType.setter
def geometryType(self, value):
self.__geometry_type = value
@property
def height(self):
return self.__height
@height.setter
def height(self, value):
self.__height = value
@property
def length(self):
return self.__length
@length.setter
def length(self, value):
self.__length = value
@property
def width(self):
return self.__width
@width.setter
def width(self, value):
self.__width = value
def to_json(self):
self.__json_out = super().to_json()
if self.geometryType is not None:
self.__json_out["geometryType"] = self.geometryType
if self.height is not None:
self.__json_out["height"] = self.height
if self.length is not None:
self.__json_out["length"] = self.length
if self.width is not None:
self.__json_out["width"] = self.width
return self.__json_out
......@@ -7,8 +7,6 @@ def __init__(self, name="", identifier=""):
identifier=identifier)
self.__stretch = None
self.__max_stretch = None
self.__min_stretch = None
@property
def stretch(self):
......@@ -18,28 +16,9 @@ def stretch(self):
def stretch(self, value):
self.__stretch = value
@property
def maxStretch(self):
return self.__max_stretch
@maxStretch.setter
def maxStretch(self, value):
self.__max_stretch = value
@property
def minStretch(self):
return self.__min_stretch
@minStretch.setter
def minStretch(self, value):
self.__min_stretch = value
def to_json(self):
self.__json_out = super().to_json()
if self.__stretch is not None:
self.__json_out["stretch"] = self.__stretch
if self.__min_stretch is not None:
self.__json_out["minStretch"] = self.__min_stretch
if self.__max_stretch is not None:
self.__json_out["maxStretch"] = self.__max_stretch
return self.__json_out
......@@ -6,6 +6,7 @@
from os.path import isfile, join, splitext
import threading
import json
from ast import literal_eval
import uuid
import time
from datetime import datetime
......@@ -15,7 +16,7 @@
import s3i.exception
from s3i.broker import Broker, BrokerREST
from s3i.messages import ServiceReply, GetValueReply, SetValueReply
from ml.tools import find_broker_endpoint, XML
from ml.tools import find_broker_endpoint, XML, DataBase
from ml.app_logger import APP_LOGGER
......@@ -45,6 +46,9 @@ def __init__(
is_stanford2010=False,
stanford2010_path=None,
stanford2010_sync_freq=None,
is_database=None,
database_conf=None,
database_file=None,
username=None,
password=None,
):
......@@ -88,6 +92,11 @@ def __init__(
self.__stanford2010_path = stanford2010_path
self.__stanford2010_sync_freq = stanford2010_sync_freq
self.__is_db = is_database
self.__db_conf = database_conf
self.__db_file = database_file
self.__db = None
self.__access_token = ""
self.__endpoint = ""
......@@ -135,6 +144,10 @@ def stanford2010(self):
def stanford2010(self, value):
self.__stanford2010 = value
@property
def db(self):
return self.__db
@property
def ditto_features(self):
return self.__ditto_features
......@@ -263,6 +276,8 @@ def run_forever(self):
if self.__is_stanford2010:
threading.Thread(target=self.__stanford2010_syn,
args=(self.__stanford2010_path, True, self.__stanford2010_sync_freq)).start()
if self.__is_db:
self.__config_database()
@staticmethod
def add_user_def(func):
......@@ -381,6 +396,11 @@ def get_last_hpr(hpr_files):
APP_LOGGER.info("Update the StanForD2010 data in DT")
self.__stanford2010 = hpr_temp
def __config_database(self):
self.__db = DataBase(db=self.__db_file,
conf=self.__db_conf)
self.__db.connect()
def __connect_with_idp(self):
"""Establishes a connection to the S³I IdentityProvider which guarantees,
that the JSON web token needed to use s3i services.
......@@ -507,11 +527,11 @@ def __on_broker_callback(self, ch, method, properties, body):
:param body: S3I-B message
"""
if isinstance(body, bytes):
try:
body = json.loads(body)
except ValueError:
body = literal_eval(body.decode('utf-8'))
except ValueError as e:
print(e)
pass
elif isinstance(body, int):
......@@ -804,7 +824,7 @@ def on_service_request(self, body_json):
if isinstance(result, bool):
result = {"ok": result}
elif result is None:
return
result = "None"
service_reply.fillServiceReply(
senderUUID=self.thing_id,
receiverUUIDs=[body_json.get("sender", None)],
......
......@@ -3,6 +3,11 @@
import json
import os
import xml.etree.ElementTree as ET
import sqlite3
import time
import jsonschema
from jsonschema import validate
from ml.app_logger import APP_LOGGER
IDENTITY_PROVIDER_URL = "https://idp.s3i.vswf.dev/"
BUILT_IN = ["from", "str", "dict", "list", "bool", "float", "int", "tuple",
......@@ -208,3 +213,113 @@ def find_nodes(self, path):
def to_string(self, root):
return self.et.tostring(root, "unicode", "xml")
class DataBase:
def __init__(self, db, conf):
self.__db = db
self.__conf = conf
self.__conn = None
def connect(self):
self.__conn = sqlite3.connect(self.__db, check_same_thread=False)
APP_LOGGER.info("Connect to the database {}".format(self.__db))
def build_table(self, table):
conf_schema = {
"type": "array",
"items": {
"type": "object",
"required": ["var_name", "var_type"],
"properties": {
"var_name": {"type": "string"},
"var_type": {"type": "string"}
}
}
}
try:
validate(instance=self.__conf, schema=conf_schema)
except jsonschema.ValidationError as e:
APP_LOGGER.error("config json error: {}".format(e))
exec_str = "ID INTEGER PRIMARY KEY AUTOINCREMENT, TIMESTAMP REAL NOT NULL"
for i in self.__conf:
name = i["var_name"]
type = i["var_type"]
exec_str += ", {} {}".format(name, type)
exec_str = '''CREATE TABLE if not exists {0} ({1});'''.format(table, exec_str)
cursor = self.__conn.cursor()
try:
cursor.execute(exec_str)
APP_LOGGER.info("Create table {} if not exists".format(table))
except sqlite3.OperationalError as e:
APP_LOGGER.warning(e)
def disconnect(self):
self.__conn.close()
def update(self, table, value_dict):
for key in value_dict.keys():
def_var_name = []
for var in self.__conf:
def_var_name.append(var["var_name"])
if key not in def_var_name:
raise ValueError("{} is not defined variable name".format(key))
timestamp = time.time()
cursor = self.__conn.cursor()
exec_str = "TIMESTAMP"
for i in self.__conf:
exec_str += ",{}".format(i["var_name"])
exec_str = "INSERT INTO {} ({})".format(table, exec_str)
value_str = "?"
for i in self.__conf:
if isinstance(value_dict[i["var_name"]], str):
value_str += ", '{}'".format(value_dict[i["var_name"]])
elif isinstance(value_dict[i["var_name"]], (float, int, bool)):
value_str += ", {}".format(value_dict[i["var_name"]])
value_str = "VALUES ({})".format(value_str)
exec_str += value_str
try:
cursor.execute(exec_str, (timestamp,))
APP_LOGGER.info("Insert new value to table {}".format(table))
except sqlite3.OperationalError as e:
APP_LOGGER.warning(e)
self.__conn.commit()
def delete(self, table, id=None):
if id is None:
exec_str = "DELETE FROM {};".format(table)
APP_LOGGER.info("delete all elements from table {}".format(table))
else:
exec_str = "DELETE FROM {} where id={}".format(table, id)
APP_LOGGER.info("delete element id {} from table {}".format(id, table))
try:
self.__conn.cursor().execute(exec_str)
except sqlite3.OperationalError as e:
APP_LOGGER.warning(e)
self.__conn.commit()
def search(self, table):
exec_str = "SELECT * FROM {};".format(table)
cursor = self.__conn.cursor().execute(exec_str)
for row in cursor:
print("------------------")
print("ID = {}".format(row[0]))
print("TIMESTAMP = {}".format(row[1]))
for i in range(len(self.__conf)):
print("{} = {}".format(self.__conf[i]["var_name"].upper(), row[i + 2]))
print("------------------\n\n")
def execute(self, exec_str):
try:
return self.__conn.cursor().execute(exec_str)
except sqlite3.OperationalError as e:
APP_LOGGER.warning(e)
......@@ -19,6 +19,7 @@
packages=setuptools.find_packages(),
install_requires=[
"requests",
"jsonschema",
"s3i@https://git.rwth-aachen.de/kwh40/s3i/-/jobs/artifacts/master/raw/public/s3i-0.4-py3-none-any.whl?job=wheel"
],
classifiers=[
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment