dt_factory.py 20 KB
Newer Older
Jiahang Chen's avatar
Jiahang Chen committed
1
""" This module implements a factory for managing and creating Digital Twins according to Forest Modeling Language 4.0."""
C. Albrecht's avatar
WIP    
C. Albrecht committed
2
3

from ml.app_logger import APP_LOGGER
4
from ml.tools import remove_namespace, check_var_conflict
Jiahang Chen's avatar
Jiahang Chen committed
5
from ml.ditto_feature import ditto_feature
Jiahang Chen's avatar
Jiahang Chen committed
6
from ml.thing import Thing
Jiahang Chen's avatar
Jiahang Chen committed
7
from ml.ml40.roles.servives.service import Service
Jiahang Chen's avatar
Jiahang Chen committed
8
9
10
11
from ml.ml40.roles.hmis.app import App
from ml.ml40.roles.hmis.dashboard import Dashboard
from ml.ml40.roles.hmis.machine_ui import MachineUI
from ml.ml40.roles.hmis.hmd import HMD
Jiahang Chen's avatar
Jiahang Chen committed
12
from ml.ml40.roles.hmis.hmi import HMI
Jiahang Chen's avatar
Jiahang Chen committed
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from ml.ml40.roles.dts.handheld_devices.handheld_device import HandheldDevice
from ml.ml40.roles.dts.machines.machine import Machine
from ml.ml40.roles.dts.parts.crane import Crane
from ml.ml40.roles.dts.parts.part import Part
from ml.ml40.roles.dts.parts.engine import Engine
from ml.ml40.roles.dts.parts.scale import Scale
from ml.ml40.roles.dts.parts.tank import Tank
from ml.ml40.roles.dts.persons.machine_operator import MachineOperator
from ml.ml40.roles.dts.persons.person import Person
from ml.ml40.roles.dts.sensors.sensor import Sensor
from ml.ml40.roles.dts.sensors.air_sensor import AirSensor
from ml.ml40.roles.dts.sensors.soil_sensor import SoilSensor
from ml.ml40.roles.dts.sites.site import Site
from ml.ml40.roles.dts.ways.way import Way

from ml.fml40.roles.dts.handheld_devices.brushcutter import Brushcutter
from ml.fml40.roles.dts.handheld_devices.chainsaw import Chainsaw
from ml.fml40.roles.dts.machines.forest_machine import ForestMachine
from ml.fml40.roles.dts.machines.forwarder import Forwarder
Jiahang Chen's avatar
Jiahang Chen committed
32
33
from ml.fml40.roles.dts.machines.harvester import Harvester
from ml.fml40.roles.dts.machines.log_truck import LogTruck
Jiahang Chen's avatar
Jiahang Chen committed
34
35
36
37
38
39
40
from ml.fml40.roles.dts.machines.mini_tractor import MiniTractor
from ml.fml40.roles.dts.machines.skidder import Skidder
from ml.fml40.roles.dts.machines.wheel_loader import WheelLoader
from ml.fml40.roles.dts.parts.grabber import Grabber
from ml.fml40.roles.dts.parts.harvesting_head import HarvestingHead
from ml.fml40.roles.dts.parts.log_loading_area import LogLoadingArea
from ml.fml40.roles.dts.parts.saw import Saw
Jiahang Chen's avatar
Jiahang Chen committed
41
from ml.fml40.roles.dts.parts.stacking_shield import StackingShield
Jiahang Chen's avatar
Jiahang Chen committed
42
43
44
45
46
from ml.fml40.roles.dts.parts.winch import Winch
from ml.fml40.roles.dts.persons.forest_owner import ForestOwner
from ml.fml40.roles.dts.persons.forest_worker import ForestWorker
from ml.fml40.roles.dts.persons.mini_tractor_operator import MiniTractorOperator
from ml.fml40.roles.dts.persons.skidder_operator import SkidderOperator
47
48
from ml.fml40.roles.dts.sensors.vitality_sensor import VitalitySensor
from ml.fml40.roles.dts.sensors.barkbeetle_sensor import BarkbeetleSensor
Jiahang Chen's avatar
Jiahang Chen committed
49
50
51
52
53
from ml.fml40.roles.dts.sites.forest_enterprise import ForestEnterprise
from ml.fml40.roles.dts.sites.hauler import Hauler
from ml.fml40.roles.dts.sites.mill.mill import Mill
from ml.fml40.roles.dts.sites.mill.papermill import Papermill
from ml.fml40.roles.dts.sites.mill.sawmill import Sawmill
Jiahang Chen's avatar
Jiahang Chen committed
54
55
56
57
58
59
from ml.fml40.roles.dts.woods.wood import Wood
from ml.fml40.roles.dts.woods.stem_segment import StemSegment
from ml.fml40.roles.dts.woods.wood_pile import WoodPile
from ml.fml40.roles.dts.forest.forest import Forest
from ml.fml40.roles.dts.forest.forest_segment import ForestSegment
from ml.fml40.roles.dts.forest.tree import Tree
Jiahang Chen's avatar
Jiahang Chen committed
60

Jiahang Chen's avatar
Jiahang Chen committed
61
from ml.mml40.roles.dts.parts.cantilever import Cantilever
Jiahang Chen's avatar
Jiahang Chen committed
62
from ml.mml40.roles.dts.sensors.strain_gauge import StrainGauge
Jiahang Chen's avatar
Jiahang Chen committed
63

Jiahang Chen's avatar
Jiahang Chen committed
64
65
from ml.ml40.features.properties.associations.association import Association
from ml.ml40.features.properties.associations.composite import Composite
Jiahang Chen's avatar
Jiahang Chen committed
66
from ml.ml40.features.properties.property import Property
Jiahang Chen's avatar
Jiahang Chen committed
67
from ml.ml40.features.properties.associations.shared import Shared
Jiahang Chen's avatar
Jiahang Chen committed
68
from ml.ml40.features.properties.values.address import Address
Jiahang Chen's avatar
Jiahang Chen committed
69
from ml.ml40.features.properties.values.count import Count
Jiahang Chen's avatar
Jiahang Chen committed
70
from ml.ml40.features.properties.values.dimensions import Dimensions
Jiahang Chen's avatar
Jiahang Chen committed
71
from ml.ml40.features.properties.values.distance import Distance
Jiahang Chen's avatar
Jiahang Chen committed
72
from ml.ml40.features.properties.values.expansion_length import ExpansionLength
Jiahang Chen's avatar
Jiahang Chen committed
73
from ml.ml40.features.properties.values.force import Force
Jiahang Chen's avatar
Jiahang Chen committed
74
from ml.ml40.features.properties.values.generic_property import GenericProperty
Jiahang Chen's avatar
Jiahang Chen committed
75
from ml.ml40.features.properties.values.last_service_check import LastServiceCheck
Jiahang Chen's avatar
Jiahang Chen committed
76
from ml.ml40.features.properties.values.lot import Lot
77
from ml.ml40.features.properties.values.lift import Lift
Jiahang Chen's avatar
Jiahang Chen committed
78
79
from ml.ml40.features.properties.values.liquid_filling_level import LiquidFillingLevel
from ml.ml40.features.properties.values.location import Location
C. Albrecht's avatar
WIP    
C. Albrecht committed
80
from ml.ml40.features.properties.values.moisture import Moisture
Jiahang Chen's avatar
Jiahang Chen committed
81
from ml.ml40.features.properties.values.operating_hours import OperatingHours
Jiahang Chen's avatar
Jiahang Chen committed
82
from ml.ml40.features.properties.values.orientation_rpy import OrientationRPY
Jiahang Chen's avatar
Jiahang Chen committed
83
84
85
from ml.ml40.features.properties.values.personal_name import PersonalName
from ml.ml40.features.properties.values.rotational_speed import RotationalSpeed
from ml.ml40.features.properties.values.route import Route
Jiahang Chen's avatar
Jiahang Chen committed
86
from ml.ml40.features.properties.values.switching_stage import SwitchingStage
Jiahang Chen's avatar
Jiahang Chen committed
87
88
89
90
91
92
93
94
from ml.ml40.features.properties.values.temperature import Temperature
from ml.ml40.features.properties.values.time_slot import TimeSlot
from ml.ml40.features.properties.values.weight import Weight
from ml.ml40.features.properties.values.documents.jobs.generic_job import GenericJob
from ml.ml40.features.properties.values.documents.jobs.job import Job
from ml.ml40.features.properties.values.documents.jobs.job_list import JobList
from ml.ml40.features.properties.values.documents.jobs.job_status import JobStatus
from ml.ml40.features.properties.values.documents.reports.report import Report
Jiahang Chen's avatar
Jiahang Chen committed
95
from ml.ml40.features.properties.values.documents.reports.production_data import ProductionData
Jiahang Chen's avatar
Jiahang Chen committed
96
97
98
99

from ml.fml40.features.properties.values.abstract_inventory import AbstractInventory
from ml.fml40.features.properties.values.assortment import Assortment
from ml.fml40.features.properties.values.dbh import DBH
Jiahang Chen's avatar
Jiahang Chen committed
100
101
from ml.fml40.features.properties.values.fell_indicator import FellIndicator
from ml.fml40.features.properties.values.felling_period import FellingPeriod
Jiahang Chen's avatar
Jiahang Chen committed
102
103
from ml.fml40.features.properties.values.harvesting_parameter import HarvestingParameters
from ml.fml40.features.properties.values.harvested_volume import HarvestedVolume
Jiahang Chen's avatar
Jiahang Chen committed
104
from ml.fml40.features.properties.values.interfering_branches import InterferingBranches
Jiahang Chen's avatar
Jiahang Chen committed
105
from ml.fml40.features.properties.values.inventory_data import InventoryData
Jiahang Chen's avatar
Jiahang Chen committed
106
from ml.fml40.features.properties.values.overhang import Overhang
Jiahang Chen's avatar
Jiahang Chen committed
107
108
109
110
111
from ml.fml40.features.properties.values.stem_segment_properties import StemSegmentProperties
from ml.fml40.features.properties.values.thickness_class import ThicknessClass
from ml.fml40.features.properties.values.tilt import Tilt
from ml.fml40.features.properties.values.tree_data import TreeData
from ml.fml40.features.properties.values.tree_type import TreeType
112
from ml.fml40.features.properties.values.vitality_status import VitalityStatus
Jiahang Chen's avatar
Jiahang Chen committed
113
114
115
116
117
118
from ml.fml40.features.properties.values.wood_quality import WoodQuality

from ml.fml40.features.properties.values.documents.jobs.felling_job import FellingJob
from ml.fml40.features.properties.values.documents.jobs.fellung_support_job import FellingSupportJob
from ml.fml40.features.properties.values.documents.jobs.forwarding_job import ForwardingJob
from ml.fml40.features.properties.values.documents.jobs.log_transportation_job import LogTransportationJob
Jiahang Chen's avatar
Jiahang Chen committed
119

Jiahang Chen's avatar
Jiahang Chen committed
120
121
122
123
124
125
126
127
128
from ml.fml40.features.properties.values.documents.reports.afforestation_suggestion import AfforestationSuggestion
from ml.fml40.features.properties.values.documents.reports.felling_tool import FellingTool
from ml.fml40.features.properties.values.documents.reports.log_measurement import LogMeasurement
from ml.fml40.features.properties.values.documents.reports.log_transportation_report import LogTransportationReport
from ml.fml40.features.properties.values.documents.reports.map_data import MapData
from ml.fml40.features.properties.values.documents.reports.moisture_prediction_report import MoisturePredictionReport
from ml.fml40.features.properties.values.documents.reports.passability_report import PassabilityReport
from ml.fml40.features.properties.values.documents.reports.soil_moisture_measurement import SoilMoistureMeasurement

Jiahang Chen's avatar
Jiahang Chen committed
129
130
131
132
from ml.mml40.features.properties.values.Displacement import Displacement
from ml.mml40.features.properties.values.MaterialProperties import MaterialProperties
from ml.mml40.features.properties.values.Stretch import Stretch

Jiahang Chen's avatar
Jiahang Chen committed
133

Jiahang Chen's avatar
Jiahang Chen committed
134
135
136
137
138
139
140
141
142
143
from ml.ml40.features.functionalities.accepts_jobs import AcceptsJobs
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.manages_jobs import ManagesJobs
from ml.ml40.features.functionalities.plans_routes import PlansRoutes
from ml.ml40.features.functionalities.provides_map_data import ProvidesMapData
from ml.ml40.features.functionalities.provides_operational_data import ProvidesOperationalData
from ml.ml40.features.functionalities.renders import Renders

C. Albrecht's avatar
WIP    
C. Albrecht committed
144
from ml.fml40.features.functionalities.accepts_felling_jobs import AcceptsFellingJobs
Jiahang Chen's avatar
Jiahang Chen committed
145
146
from ml.fml40.features.functionalities.accepts_felling_support_jobs import AcceptsFellingSupportJobs
from ml.fml40.features.functionalities.accepts_forwarding_jobs import AcceptsForwardingJobs
Jiahang Chen's avatar
Jiahang Chen committed
147
148
149
150
151
152
from ml.fml40.features.functionalities.accepts_log_measurements import AcceptsLogMeasurements
from ml.fml40.features.functionalities.accepts_log_transportaition_jobs import AcceptsLogTransportationJobs
from ml.fml40.features.functionalities.accepts_moisture_measurement import AcceptsMoistureMeasurement
from ml.fml40.features.functionalities.accepts_move_commands import AcceptsMoveCommands
from ml.fml40.features.functionalities.accepts_passability_report import AcceptsPassabilityReport
from ml.fml40.features.functionalities.accepts_proximity_alert import AcceptsProximityAlert
153
from ml.fml40.features.functionalities.accepts_shield_commands import AcceptsShieldCommands
Jiahang Chen's avatar
Jiahang Chen committed
154
from ml.fml40.features.functionalities.accepts_single_tree_felling_jobs import AcceptsSingleTreeFellingJobs
Jiahang Chen's avatar
Jiahang Chen committed
155
from ml.fml40.features.functionalities.accepts_winch_command import AcceptsWinchCommands
Jiahang Chen's avatar
Jiahang Chen committed
156
157
158
159
160
161
162
from ml.fml40.features.functionalities.classifies_tree_species import ClassifiesTreeSpecies
from ml.fml40.features.functionalities.cuts import Cuts
from ml.fml40.features.functionalities.determines_passability import DeterminesPassability
from ml.fml40.features.functionalities.displays_health_alarms import DisplaysHealthAlarms
from ml.fml40.features.functionalities.evaluates_stand_attributes import EvaluatesStandAttributes
from ml.fml40.features.functionalities.fells import Fells
from ml.fml40.features.functionalities.forest_planning_evaluation import ForestPlanningEvaluation
C. Albrecht's avatar
WIP    
C. Albrecht committed
163
from ml.fml40.features.functionalities.forwards import Forwards
Jiahang Chen's avatar
Jiahang Chen committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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.grabs import Grabs
from ml.fml40.features.functionalities.harvests import Harvests
from ml.fml40.features.functionalities.measure_wood import MeasuresWood
from ml.fml40.features.functionalities.monitor_health_status import MonitorsHealthStatus
from ml.fml40.features.functionalities.provides_moisture_prediction import ProvidesMoisturePrediction
from ml.fml40.features.functionalities.provides_passability_information import ProvidesPassabilityInformation
from ml.fml40.features.functionalities.provides_production_data import ProvidesProductionData
from ml.fml40.features.functionalities.provides_tree_data import ProvidesTreeData
from ml.fml40.features.functionalities.provides_weather_data import ProvidesWeatherData
from ml.fml40.features.functionalities.simulates_tree_growth import SimulatesTreeGrowth
from ml.fml40.features.functionalities.supports_felling import SupportsFelling
from ml.fml40.features.functionalities.transports_logs import TransportsLogs
C. Albrecht's avatar
WIP    
C. Albrecht committed
178

Jiahang Chen's avatar
Jiahang Chen committed
179
180
181
from ml.mml40.features.functionalities.ProvidesDisplacementData import ProvidesDisplacementData
from ml.mml40.features.functionalities.ProvidesForceData import ProvidesForceData
from ml.mml40.features.functionalities.ProvidesStretchData import ProvidesStretchData
C. Albrecht's avatar
WIP    
C. Albrecht committed
182
# TODO: Get rid of this global variable
Jiahang Chen's avatar
Jiahang Chen committed
183
# TODO: automatically get all classes in module
C. Albrecht's avatar
WIP    
C. Albrecht committed
184
185
DT_FACTORY = {}

Jiahang Chen's avatar
Jiahang Chen committed
186
187
188
189
190
import sys, inspect

clsmembers = inspect.getmembers(sys.modules[__name__], inspect.isclass)
for member in clsmembers:
    DT_FACTORY[member[0]] = member[1]
C. Albrecht's avatar
WIP    
C. Albrecht committed
191

Jiahang Chen's avatar
Jiahang Chen committed
192

Jiahang Chen's avatar
Jiahang Chen committed
193
def build_sub_features(feature_ins, feature):
Jiahang Chen's avatar
Jiahang Chen committed
194
    """
Jiahang Chen's avatar
Jiahang Chen committed
195
    Instantiates and inserts ml40/fml40 sub features object into feature instance
C. Albrecht's avatar
WIP    
C. Albrecht committed
196

Jiahang Chen's avatar
Jiahang Chen committed
197
    :param feature_ins: ml40/fml40 feature instance, which has a sub feature to be built
Jiahang Chen's avatar
Jiahang Chen committed
198
    :type feature_ins: object
Jiahang Chen's avatar
Jiahang Chen committed
199
    :param feature: ml40/fml40 feature containing subFeatures
Jiahang Chen's avatar
Jiahang Chen committed
200
201
202
203
    :type feature: dict

    """
    sub_features = feature.get("subFeatures", [])
Jiahang Chen's avatar
Jiahang Chen committed
204
    ### Because of the uniqueness of subfeatures, like ml40::JobList can have many fml40::ForwardingJob in subFeatures
Jiahang Chen's avatar
Jiahang Chen committed
205
    for sub_f in sub_features:
Jiahang Chen's avatar
Jiahang Chen committed
206
207
208
        sub_f_name = sub_f.get("name")
        if sub_f_name is None:
            sub_f_name = sub_f.get("class", "")
Jiahang Chen's avatar
Jiahang Chen committed
209
210
        _class_name = sub_f.get("class", "")
        sub_f_obj = DT_FACTORY.get(remove_namespace(_class_name), None)
Jiahang Chen's avatar
Jiahang Chen committed
211
        if sub_f_obj is None:
Jiahang Chen's avatar
Jiahang Chen committed
212
            APP_LOGGER.critical("Subfeature: %s is missing" % _class_name)
C. Albrecht's avatar
WIP    
C. Albrecht committed
213
        else:
Jiahang Chen's avatar
Jiahang Chen committed
214
            APP_LOGGER.info("Adding subfeature: %s" % _class_name)
Jiahang Chen's avatar
Jiahang Chen committed
215
216
            sub_f_instance = sub_f_obj()
            for key in sub_f.keys():
Jiahang Chen's avatar
Jiahang Chen committed
217
                if key == "targets":
Jiahang Chen's avatar
Jiahang Chen committed
218
                    build_sub_thing(sub_f_instance, sub_f)
Jiahang Chen's avatar
Jiahang Chen committed
219
                elif key == "subFeatures":
Jiahang Chen's avatar
Jiahang Chen committed
220
                    build_sub_features(sub_f_instance, sub_f)
Jiahang Chen's avatar
Jiahang Chen committed
221
                else:
Jiahang Chen's avatar
Jiahang Chen committed
222
223
                    setattr(sub_f_instance, key, sub_f[key])
            feature_ins.subFeatures[sub_f_name] = sub_f_instance
Jiahang Chen's avatar
Jiahang Chen committed
224
225


Jiahang Chen's avatar
Jiahang Chen committed
226
227
def build_sub_thing(feature_ins, feature):
    """
Jiahang Chen's avatar
Jiahang Chen committed
228
    Instantiates and inserts sub thing object into a feature instance
Jiahang Chen's avatar
Jiahang Chen committed
229
230
231

    :param feature_ins: ml40/fml40 feature instance
    :type feature_ins: object
Jiahang Chen's avatar
Jiahang Chen committed
232
    :param feature: ml40/fml40 feature, which contains a sub thing
Jiahang Chen's avatar
Jiahang Chen committed
233
234
235
236
    :type feature: dict

    """
    json_sub_things = feature.get("targets", [])
Jiahang Chen's avatar
Jiahang Chen committed
237
    for json_sub_thing in json_sub_things:
Jiahang Chen's avatar
Jiahang Chen committed
238
        sub_thing_ref = create_thing(model={"attributes": json_sub_thing})
Jiahang Chen's avatar
Jiahang Chen committed
239
240
        sub_thing_name = json_sub_thing.get("name", None)
        feature_ins.targets[sub_thing_name] = sub_thing_ref
C. Albrecht's avatar
WIP    
C. Albrecht committed
241
242


Jiahang Chen's avatar
Jiahang Chen committed
243
def build(thing, model):
Jiahang Chen's avatar
Jiahang Chen committed
244
    """
Jiahang Chen's avatar
Jiahang Chen committed
245
    Builds a ml40 thing instance
Jiahang Chen's avatar
Jiahang Chen committed
246
247
248

    :param thing: ml40 thing instance
    :type thing: object
Jiahang Chen's avatar
Jiahang Chen committed
249
250
    :param model: model in ml40 thing JSON
    :type model: dict
Jiahang Chen's avatar
Jiahang Chen committed
251
252

    """
Jiahang Chen's avatar
Jiahang Chen committed
253
254
255
256
    attributes = model.get("attributes", None)
    ditto_features = model.get("features", None)

    if not isinstance(model, dict):
Jiahang Chen's avatar
Jiahang Chen committed
257
        # TODO JSON Schema
Jiahang Chen's avatar
Jiahang Chen committed
258
        APP_LOGGER.critical("model is no valid JSON")
Jiahang Chen's avatar
Jiahang Chen committed
259
        return
Jiahang Chen's avatar
Jiahang Chen committed
260
    roles = attributes.get("roles", [])
Jiahang Chen's avatar
Jiahang Chen committed
261
    for role in roles:
Jiahang Chen's avatar
Jiahang Chen committed
262
263
        role_instance = build_role(role)
        thing.roles[role.get("class")] = role_instance
Jiahang Chen's avatar
Jiahang Chen committed
264

Jiahang Chen's avatar
Jiahang Chen committed
265
266
267
268
269
    json_features = attributes.get("features", [])
    for feature in json_features:
        feature_ins = build_feature(feature=feature)
        thing.features[feature.get("class")] = feature_ins

Jiahang Chen's avatar
Jiahang Chen committed
270
271
272
273
274
275
276
    if ditto_features is not None:
        build_ditto_features(thing, ditto_features)


def build_ditto_features(thing, ditto_features):
    for id in ditto_features.keys():
        for key in ditto_features[id]["properties"]:
Jiahang Chen's avatar
Jiahang Chen committed
277
278
            ditto_f = ditto_feature(id=id, key=key, value=ditto_features[id]["properties"][key])
        thing.ditto_features[ditto_f.id] = ditto_f
Jiahang Chen's avatar
Jiahang Chen committed
279

Jiahang Chen's avatar
Jiahang Chen committed
280
281

def build_role(role):
Jiahang Chen's avatar
Jiahang Chen committed
282
    """
Jiahang Chen's avatar
Jiahang Chen committed
283
     Instantiates and inserts a ml40/fml40 role object into a ml40 thing instance
Jiahang Chen's avatar
Jiahang Chen committed
284
285
286
287
288

    :param role: ml40/fml40 role
    :type role: dict

    """
Jiahang Chen's avatar
Jiahang Chen committed
289
290
291
292
    role_class_name = role.get("class", "")
    role_obj = DT_FACTORY.get(remove_namespace(role_class_name), None)
    if role_obj is None:
        APP_LOGGER.critical("Roles: %s is missing" % role_class_name)
Jiahang Chen's avatar
Jiahang Chen committed
293
        role_instance = None
Jiahang Chen's avatar
Jiahang Chen committed
294
    else:
Jiahang Chen's avatar
Jiahang Chen committed
295
        APP_LOGGER.info("Adding roles: %s" % role_class_name)
Jiahang Chen's avatar
Jiahang Chen committed
296
297
298
299
300
        role_instance = role_obj()
    return role_instance


def build_feature(feature):
Jiahang Chen's avatar
Jiahang Chen committed
301
    """
Jiahang Chen's avatar
Jiahang Chen committed
302
     Instantiates and inserts a ml40/fml40 feature object in a ml40 thing instance
Jiahang Chen's avatar
Jiahang Chen committed
303
304
305
306
307

    :param feature: ml40/fml40 feature
    :type feature: dict

    """
Jiahang Chen's avatar
Jiahang Chen committed
308
309
310
311
312
    feature_class_name = feature.get("class", "")
    feature_obj = DT_FACTORY.get(remove_namespace(feature_class_name), None)

    if feature_obj is None:
        APP_LOGGER.critical("Feature: %s is missing" % feature_class_name)
Jiahang Chen's avatar
Jiahang Chen committed
313
        feature_instance = None
Jiahang Chen's avatar
Jiahang Chen committed
314
    else:
Jiahang Chen's avatar
Jiahang Chen committed
315
        APP_LOGGER.info("Adding feature: %s" % feature_class_name)
Jiahang Chen's avatar
Jiahang Chen committed
316
317
        feature_instance = feature_obj()
        for key in feature.keys():
Jiahang Chen's avatar
Jiahang Chen committed
318
319
            if key == "class":
                continue
Jiahang Chen's avatar
Jiahang Chen committed
320
321
322
323
324
            if key == "targets":
                build_sub_thing(feature_instance, feature)
            elif key == "subFeatures":
                build_sub_features(feature_instance, feature)
            else:
325
                setattr(feature_instance, check_var_conflict(key), feature[key])
Jiahang Chen's avatar
Jiahang Chen committed
326
327
328
    return feature_instance


329
def add_function_impl_obj(thing, impl_obj, feature_name, **kwargs):
Jiahang Chen's avatar
Jiahang Chen committed
330
    """
Jiahang Chen's avatar
Jiahang Chen committed
331
    Adds user-specific implemented object to a thing instance
Jiahang Chen's avatar
Jiahang Chen committed
332
333
334
335
336
337
338
339
340
341

    :param thing: ml40 thing instance
    :type thing: object
    :param impl_obj: ml40/fml40 feature instance
    :type impl_obj: object
    :param feature_name: class name of a ml40/fml40 feature
    :type feature_name: str


    """
Jiahang Chen's avatar
Jiahang Chen committed
342
343
344
345
346
347
    feature = thing.features.get(feature_name, None)
    if feature is None:
        APP_LOGGER.critical(
            "Functionality %s is not one of the build-in functionalities" % feature_name
        )
    else:
Jiahang Chen's avatar
Jiahang Chen committed
348
        APP_LOGGER.info("Implementation object is added into the functionality %s" % feature_name)
349
        impl_ins = impl_obj(**kwargs)
Jiahang Chen's avatar
Jiahang Chen committed
350
351
        impl_ins.class_name = feature_name
        thing.features[feature_name] = impl_ins
Jiahang Chen's avatar
Jiahang Chen committed
352
353


Jiahang Chen's avatar
Jiahang Chen committed
354
355
def create_thing(model, grant_type="password",
                 secret="", username=None, password=None,
Jiahang Chen's avatar
Jiahang Chen committed
356
                 is_broker_rest=False, is_broker=False, is_repo=False, is_stanford2010=False,
Jiahang Chen's avatar
Jiahang Chen committed
357
                 is_stanford2010_sync=False,
Jiahang Chen's avatar
Jiahang Chen committed
358
359
                 stanford2010_sync_freq=None, stanford2010_path=None, is_database=False,
                 database_conf=None, database_file=None):
Jiahang Chen's avatar
Jiahang Chen committed
360
    """
Jiahang Chen's avatar
Jiahang Chen committed
361
    Creates and launches a thing which connects to the S3I
Jiahang Chen's avatar
Jiahang Chen committed
362

Jiahang Chen's avatar
Jiahang Chen committed
363
    :param model: edge-device or S³I Repository specified JSON entry
Jiahang Chen's avatar
Jiahang Chen committed
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
    :type model: dict
    :param grant_type: grant type of OAuth2.0, which can be password or client_credentials
    :type grant_type: str
    :param secret: secret of a thing
    :type secret: str
    :param username: username, if the grant_type is set as password, the username is required
    :type username: str
    :param password: password, if the grant_type is set as password, the password is required
    :type password: str
    :param is_broker: whether broker interface is enabled in the ml40::thing instance
    :type is_broker: bool
    :param is_broker_rest: whether the broker interface uses the HTTP REST
    :type is_broker_rest: bool
    :param is_repo: whether the repository interface is enabled in the ml40::thing instance
    :type is_repo: bool

    :returns: ml40::thing instance
    :rtype: object

    """
C. Albrecht's avatar
WIP    
C. Albrecht committed
384
385
    attributes = model.get("attributes", None)
    if attributes is None:
Jiahang Chen's avatar
Jiahang Chen committed
386
        sys.exit("attributes are none")
Jiahang Chen's avatar
Jiahang Chen committed
387
    thing_type = remove_namespace(attributes.get("class", ""))
C. Albrecht's avatar
WIP    
C. Albrecht committed
388
    thing_name = attributes.get("name", "")
Jiahang Chen's avatar
Jiahang Chen committed
389
    APP_LOGGER.info("Build digital twin {} with id {}".format(thing_name, model.get("thingId", "")))
Jiahang Chen's avatar
Jiahang Chen committed
390

Jiahang Chen's avatar
Jiahang Chen committed
391
    _thing = DT_FACTORY.get(thing_type)
Jiahang Chen's avatar
Jiahang Chen committed
392

Jiahang Chen's avatar
Jiahang Chen committed
393
    thing_ref = _thing(
C. Albrecht's avatar
WIP    
C. Albrecht committed
394
395
396
397
398
        model=model,
        grant_type=grant_type,
        client_secret=secret,
        username=username,
        password=password,
Jiahang Chen's avatar
Jiahang Chen committed
399
        is_broker_rest=is_broker_rest,
C. Albrecht's avatar
WIP    
C. Albrecht committed
400
        is_broker=is_broker,
Jiahang Chen's avatar
Jiahang Chen committed
401
402
        is_repo=is_repo,
        is_stanford2010=is_stanford2010,
Jiahang Chen's avatar
Jiahang Chen committed
403
        stanford2010_sync_freq=stanford2010_sync_freq,
Jiahang Chen's avatar
Jiahang Chen committed
404
        is_stanford2010_sync=is_stanford2010_sync,
Jiahang Chen's avatar
Jiahang Chen committed
405
406
407
        stanford2010_path=stanford2010_path,
        is_database=is_database,
        database_file=database_file,
C. Albrecht's avatar
WIP    
C. Albrecht committed
408
    )
Jiahang Chen's avatar
Jiahang Chen committed
409
410
    build(thing_ref, model)

C. Albrecht's avatar
WIP    
C. Albrecht committed
411
    return thing_ref