Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
KWH40
fml40-reference-implementation
Commits
316b2fbf
Commit
316b2fbf
authored
Dec 02, 2020
by
GromeTT
Browse files
ENH: Added documentation for thing.py
parent
1be54e4b
Changes
1
Show whitespace changes
Inline
Side-by-side
ml/thing.py
View file @
316b2fbf
"""This module implements the thing class which is the core element of
this package."""
import
ast
import
threading
import
json
...
...
@@ -61,9 +64,12 @@ def __init__(
self
.
__ws_connected
=
False
self
.
broker
=
None
self
.
ws
=
None
# TODO: Change the variable name dir, because it is a builtin
# name.
self
.
dir
=
None
self
.
repo
=
None
# : Dict[<str>, <str>]
self
.
repo_json
=
dict
()
self
.
dir_json
=
dict
()
self
.
dt_json
=
dict
()
...
...
@@ -72,6 +78,7 @@ def __init__(
self
.
__name
=
""
self
.
__roles
=
{}
self
.
__features
=
{}
# ??? Is this property necessary? Only used as return value in _getValue()
self
.
__resGetValue
=
list
()
if
attributes
:
self
.
__name
=
attributes
.
get
(
"name"
,
""
)
...
...
@@ -100,6 +107,12 @@ def features(self):
@
features
.
setter
def
features
(
self
,
value
):
"""Replaces __features with vale.
:param value: New collection of features
"""
self
.
__features
=
value
@
property
...
...
@@ -188,6 +201,7 @@ def policy_id(self):
def
run_forever
(
self
):
"""Starts the thing in permanent mode.
"""
# TODO: Use logger instead!
...
...
@@ -201,6 +215,12 @@ def run_forever(self):
@
staticmethod
def
add_user_def
(
func
):
"""Runs func in a thread.
:param func: Function to be executed.
"""
threading
.
Thread
(
target
=
func
).
start
()
def
__json_syn
(
self
,
freq
=
0.1
):
...
...
@@ -213,7 +233,7 @@ def __json_syn(self, freq=0.1):
continue
def
__dir_syn
(
self
,
freq
=
0.1
):
"""Applies local changes to the directory entry.
"""Applies local changes to the directory entry
in the cloud
.
:param freq: Frequency of the update.
"""
...
...
@@ -232,7 +252,7 @@ def __dir_syn(self, freq=0.1):
# continue
def
__repo_syn
(
self
,
freq
=
0.1
):
"""Applies local changes to the repository entry.
"""Applies local changes to the repository entry
in the cloud
.
:param freq: Frequency of the update.
"""
...
...
@@ -241,6 +261,7 @@ def __repo_syn(self, freq=0.1):
time
.
sleep
(
freq
)
old_repo_json
=
self
.
repo_json
self
.
to_repo_json
()
# TODO: Clean up this reqion
if
self
.
repo_json
==
old_repo_json
:
continue
else
:
...
...
@@ -251,7 +272,9 @@ def __repo_syn(self, freq=0.1):
continue
def
__connect_with_idp
(
self
):
"""
"""Establishes a connection to the identity provider which guarantees,
that the java web token needed to use s3i online services will
be renewed if it has expired.
"""
...
...
@@ -276,6 +299,13 @@ def __connect_with_idp(self):
idp
.
run_forever
(
token_type
=
TokenType
.
ACCESS_TOKEN
,
on_new_token
=
self
.
__on_token
)
def
__on_token
(
self
,
token
):
"""Updates the java web token with token and reestablishes connections
to the s3i online services.
:param token: New java web token
"""
self
.
__access_token
=
token
self
.
__connect_with_dir
()
self
.
__connect_with_repo
()
...
...
@@ -283,6 +313,15 @@ def __on_token(self, token):
self
.
__connect_with_broker
()
def
__connect_with_dir
(
self
):
"""Initializes the property dir with a Directory object which can be
used to access the s3i directory online service.
:returns:
:rtype:
"""
# TODO: Use logger
print
(
BColors
.
OKBLUE
+
"[S³I][Dir]"
...
...
@@ -294,6 +333,15 @@ def __connect_with_dir(self):
)
def
__connect_with_repo
(
self
):
"""Initializes the property repo whit a Repository object which can be
used to access the s3i repository online service.
:returns:
:rtype:
"""
# TODO: Use logger
print
(
BColors
.
OKBLUE
+
"[S³I][Repo]"
...
...
@@ -305,6 +353,13 @@ def __connect_with_repo(self):
)
def
__connect_with_broker
(
self
):
"""Initializes the property broker with a Broker object. Additionally
a callback function is registered which handles incoming S3I-B
messages.
"""
# TODO: Use logger
print
(
BColors
.
OKBLUE
+
"[S³I][Broker]"
...
...
@@ -348,6 +403,14 @@ def receive():
).
start
()
def
__on_broker_callback
(
self
,
ch
,
method
,
properties
,
body
):
"""Parses body (content of a S3I-B message) and delegates the
processing of the message to a separate method. The method is
selected according to the message's type.
:param body: S3I-B message
"""
if
isinstance
(
body
,
bytes
):
body_str
=
body
.
decode
(
'utf8'
).
replace
(
"'"
,
'"'
)
try
:
...
...
@@ -376,6 +439,12 @@ def __on_broker_callback(self, ch, method, properties, body):
pass
def
on_user_message
(
self
,
msg
):
"""Handles Prints msg to stdout.
:param msg: S3I-B message
"""
print
(
BColors
.
OKBLUE
+
"[S³I][Broker]"
...
...
@@ -385,6 +454,13 @@ def on_user_message(self, msg):
)
def
on_get_value_request
(
self
,
msg
):
"""Handles GetValueRequest message. Looks up the value specified in msg and
sends a GetValueReply message back to the sender.
:param msg: GetValueRequest
"""
print
(
BColors
.
OKBLUE
+
"[S³I][Broker]"
...
...
@@ -438,6 +514,13 @@ def on_get_value_request(self, msg):
+
res
.
text
)
def
_uriToData
(
self
,
uri
):
"""Returns a copy of the value found at uri.
:param uri: Path to value
:rtype: Feature
"""
if
uri
==
""
:
return
self
.
dt_json
else
:
...
...
@@ -462,6 +545,17 @@ def _uriToData(self, uri):
return
response
def
_getValue
(
self
,
source
,
uri_list
):
"""Searches for the value specified by uri_list in source and stores
the result in __resGetValue.
:param source: Object that is scanned
:param uri_list: List containing path
"""
# ??? What if the uri points to a Value object?
# Shouldn't it be serialized?!
value
=
source
[
uri_list
[
0
]]
if
uri_list
.
__len__
()
==
1
:
# if is ditto-feature
...
...
@@ -477,6 +571,7 @@ def _getValue(self, source, uri_list):
self
.
__resGetValue
.
append
(
value
)
return
if
isinstance
(
value
,
dict
):
# ??? uri_list.pop(0) better?!
del
uri_list
[
0
]
self
.
_getValue
(
value
,
uri_list
)
if
isinstance
(
value
,
list
):
...
...
@@ -513,6 +608,16 @@ def _getValue(self, source, uri_list):
self
.
__resGetValue
.
append
(
value
)
def
_findValue
(
self
,
json
,
value
):
"""Returns true if value has been found in json, otherwise returns false.
:param json: dictionary
:param value:
:returns:
:rtype:
"""
# TODO: Simplify: value in json.values()
for
item
in
json
:
if
json
[
item
]
==
value
:
# print("Parameter: ", json[item])
...
...
@@ -520,6 +625,14 @@ def _findValue(self, json, value):
return
False
def
on_service_request
(
self
,
body_json
):
"""Handles ServiceRequest messages. Executes the method of the
functionality specified in body_json and send a ServiceReply
back to the sender.
:param body_json: ServiceRequest
"""
print
(
BColors
.
OKBLUE
+
"[S³I][Broker]"
...
...
@@ -603,6 +716,14 @@ def on_service_request(self, body_json):
+
res
.
text
)
def
on_get_value_reply
(
self
,
msg
):
"""Handles GetValueReply messsage. Prints the content of msg to stdout.
:param msg: GetValueReply
"""
# ???: Behavior should be defined by the user! Maybe he want
# to process the result!
print
(
BColors
.
OKBLUE
+
"[S³I][Broker]"
...
...
@@ -624,6 +745,12 @@ def on_get_value_reply(self, msg):
)
def
on_service_reply
(
self
,
msg
):
"""Handles ServiceReply messages. Prints the content of msg to stdout.
:param msg: ServiceReply
"""
print
(
BColors
.
OKBLUE
+
"[S³I][Broker]"
...
...
@@ -645,6 +772,13 @@ def on_service_reply(self, msg):
)
def
to_dir_json
(
self
):
"""Returns a dictionary representing this thing's directory entry.
:returns: Directory representation of this object
:rtype: dict
"""
self
.
dir_json
=
self
.
dir
.
queryThingIDBased
(
self
.
thing_id
)
if
self
.
thing_id
is
not
None
:
self
.
dir_json
[
"thingId"
]
=
self
.
thing_id
...
...
@@ -684,10 +818,24 @@ def to_dir_json(self):
return
self
.
dir_json
def
to_repo_json
(
self
):
"""Returns a dictionary representing this thing's repository entry.
:returns: Repository representation of this object
:rtype: dict
"""
self
.
repo_json
=
self
.
dt_json
return
self
.
repo_json
def
to_json
(
self
):
"""Returns a dictionary representing this thing in it's current state.
:returns: Representation of this object
:rtype: dict
"""
self
.
dt_json
=
{
"thingId"
:
self
.
thing_id
,
"policyId"
:
self
.
policy_id
,
...
...
@@ -707,6 +855,13 @@ def to_json(self):
return
self
.
dt_json
def
to_subthing_json
(
self
):
"""
:returns:
:rtype:
"""
json_out
=
{
"class"
:
"ml40::Thing"
,
"identifier"
:
self
.
thing_id
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment