Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
opcua-asyncio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nikola Balog
opcua-asyncio
Commits
af5a31c0
Commit
af5a31c0
authored
May 03, 2021
by
oroulet
Committed by
oroulet
May 04, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix use of continuation point in server history
parent
2cf565e2
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
26 additions
and
18 deletions
+26
-18
asyncua/common/node.py
asyncua/common/node.py
+1
-1
asyncua/server/history.py
asyncua/server/history.py
+14
-3
asyncua/server/history_sql.py
asyncua/server/history_sql.py
+10
-13
examples/client-example.py
examples/client-example.py
+1
-1
No files found.
asyncua/common/node.py
View file @
af5a31c0
...
@@ -543,7 +543,7 @@ class Node:
...
@@ -543,7 +543,7 @@ class Node:
# No more data available
# No more data available
if
continuation_point
is
None
:
if
continuation_point
is
None
:
break
break
return
history
return
history
async
def
history_read
(
self
,
details
,
continuation_point
=
None
):
async
def
history_read
(
self
,
details
,
continuation_point
=
None
):
...
...
asyncua/server/history.py
View file @
af5a31c0
...
@@ -20,6 +20,8 @@ class HistoryStorageInterface:
...
@@ -20,6 +20,8 @@ class HistoryStorageInterface:
Interface of a history backend.
Interface of a history backend.
Must be implemented by backends
Must be implemented by backends
"""
"""
def
__init__
(
self
,
max_history_data_response_size
=
10000
):
self
.
max_history_data_response_size
=
max_history_data_response_size
async
def
init
(
self
):
async
def
init
(
self
):
"""
"""
...
@@ -89,7 +91,8 @@ class HistoryDict(HistoryStorageInterface):
...
@@ -89,7 +91,8 @@ class HistoryDict(HistoryStorageInterface):
Very minimal history backend storing data in memory using a Python dictionary
Very minimal history backend storing data in memory using a Python dictionary
"""
"""
def
__init__
(
self
):
def
__init__
(
self
,
max_history_data_response_size
=
10000
):
self
.
max_history_data_response_size
=
max_history_data_response_size
self
.
_datachanges
=
{}
self
.
_datachanges
=
{}
self
.
_datachanges_period
=
{}
self
.
_datachanges_period
=
{}
self
.
_events
=
{}
self
.
_events
=
{}
...
@@ -144,9 +147,13 @@ class HistoryDict(HistoryStorageInterface):
...
@@ -144,9 +147,13 @@ class HistoryDict(HistoryStorageInterface):
results
=
[
results
=
[
dv
for
dv
in
self
.
_datachanges
[
node_id
]
if
start
<=
dv
.
SourceTimestamp
<=
end
dv
for
dv
in
self
.
_datachanges
[
node_id
]
if
start
<=
dv
.
SourceTimestamp
<=
end
]
]
if
nb_values
and
len
(
results
)
>
nb_values
:
if
nb_values
and
len
(
results
)
>
nb_values
:
cont
=
results
[
nb_values
+
1
].
SourceTimestamp
results
=
results
[:
nb_values
]
results
=
results
[:
nb_values
]
if
len
(
results
)
>
self
.
max_history_data_response_size
:
cont
=
results
[
self
.
max_history_data_response_size
+
1
].
SourceTimestamp
results
=
results
[:
self
.
max_history_data_response_size
]
return
results
,
cont
return
results
,
cont
async
def
new_historized_event
(
self
,
source_id
,
evtypes
,
period
,
count
=
0
):
async
def
new_historized_event
(
self
,
source_id
,
evtypes
,
period
,
count
=
0
):
...
@@ -190,9 +197,13 @@ class HistoryDict(HistoryStorageInterface):
...
@@ -190,9 +197,13 @@ class HistoryDict(HistoryStorageInterface):
else
:
else
:
results
=
[
ev
for
ev
in
self
.
_events
[
source_id
]
if
start
<=
ev
.
Time
<=
end
]
results
=
[
ev
for
ev
in
self
.
_events
[
source_id
]
if
start
<=
ev
.
Time
<=
end
]
if
nb_values
and
len
(
results
)
>
nb_values
:
if
nb_values
and
len
(
results
)
>
nb_values
:
cont
=
results
[
nb_values
+
1
].
Time
results
=
results
[:
nb_values
]
results
=
results
[:
nb_values
]
if
len
(
results
)
>
self
.
max_history_data_response_size
:
cont
=
results
[
self
.
max_history_data_response_size
+
1
].
Time
results
=
results
[:
self
.
max_history_data_response_size
]
return
results
,
cont
return
results
,
cont
async
def
stop
(
self
):
async
def
stop
(
self
):
...
...
asyncua/server/history_sql.py
View file @
af5a31c0
...
@@ -4,7 +4,6 @@ import sqlite3
...
@@ -4,7 +4,6 @@ import sqlite3
from
typing
import
Iterable
from
typing
import
Iterable
from
datetime
import
timedelta
from
datetime
import
timedelta
from
datetime
import
datetime
from
datetime
import
datetime
from
asyncio
import
get_event_loop
from
asyncua
import
ua
from
asyncua
import
ua
from
..ua.ua_binary
import
variant_from_binary
,
variant_to_binary
from
..ua.ua_binary
import
variant_from_binary
,
variant_to_binary
...
@@ -21,16 +20,16 @@ class HistorySQLite(HistoryStorageInterface):
...
@@ -21,16 +20,16 @@ class HistorySQLite(HistoryStorageInterface):
note that PARSE_DECLTYPES is active so certain data types (such as datetime) will not be BLOBs
note that PARSE_DECLTYPES is active so certain data types (such as datetime) will not be BLOBs
"""
"""
def
__init__
(
self
,
path
=
"history.db"
,
loop
=
None
):
def
__init__
(
self
,
path
=
"history.db"
,
max_history_data_response_size
=
10000
):
self
.
max_history_data_response_size
=
max_history_data_response_size
self
.
logger
=
logging
.
getLogger
(
__name__
)
self
.
logger
=
logging
.
getLogger
(
__name__
)
self
.
_datachanges_period
=
{}
self
.
_datachanges_period
=
{}
self
.
_db_file
=
path
self
.
_db_file
=
path
self
.
_event_fields
=
{}
self
.
_event_fields
=
{}
self
.
_db
:
aiosqlite
.
Connection
=
None
self
.
_db
:
aiosqlite
.
Connection
=
None
self
.
_loop
=
loop
or
get_event_loop
()
async
def
init
(
self
):
async
def
init
(
self
):
self
.
_db
=
await
aiosqlite
.
connect
(
self
.
_db_file
,
loop
=
self
.
_loop
,
detect_types
=
sqlite3
.
PARSE_DECLTYPES
)
self
.
_db
=
await
aiosqlite
.
connect
(
self
.
_db_file
,
detect_types
=
sqlite3
.
PARSE_DECLTYPES
)
async
def
stop
(
self
):
async
def
stop
(
self
):
await
self
.
_db
.
close
()
await
self
.
_db
.
close
()
...
@@ -123,10 +122,9 @@ class HistorySQLite(HistoryStorageInterface):
...
@@ -123,10 +122,9 @@ class HistorySQLite(HistoryStorageInterface):
results
.
append
(
dv
)
results
.
append
(
dv
)
except
aiosqlite
.
Error
as
e
:
except
aiosqlite
.
Error
as
e
:
self
.
logger
.
error
(
"Historizing SQL Read Error for %s: %s"
,
node_id
,
e
)
self
.
logger
.
error
(
"Historizing SQL Read Error for %s: %s"
,
node_id
,
e
)
if
nb_values
:
if
len
(
results
)
>
self
.
max_history_data_response_size
:
if
len
(
results
)
>
nb_values
:
cont
=
results
[
self
.
max_history_data_response_size
].
SourceTimestamp
cont
=
results
[
nb_values
].
SourceTimestamp
results
=
results
[:
self
.
max_history_data_response_size
]
results
=
results
[:
nb_values
]
return
results
,
cont
return
results
,
cont
async
def
new_historized_event
(
self
,
source_id
,
evtypes
,
period
,
count
=
0
):
async
def
new_historized_event
(
self
,
source_id
,
evtypes
,
period
,
count
=
0
):
...
@@ -199,10 +197,9 @@ class HistorySQLite(HistoryStorageInterface):
...
@@ -199,10 +197,9 @@ class HistorySQLite(HistoryStorageInterface):
results
.
append
(
Event
.
from_field_dict
(
fdict
))
results
.
append
(
Event
.
from_field_dict
(
fdict
))
except
aiosqlite
.
Error
as
e
:
except
aiosqlite
.
Error
as
e
:
self
.
logger
.
error
(
"Historizing SQL Read Error events for node %s: %s"
,
source_id
,
e
)
self
.
logger
.
error
(
"Historizing SQL Read Error events for node %s: %s"
,
source_id
,
e
)
if
nb_values
:
if
len
(
results
)
>
self
.
max_history_data_response_size
:
# start > ua.get_win_epoch() and
if
len
(
results
)
>
nb_values
:
# start > ua.get_win_epoch() and
cont
=
cont_timestamps
[
self
.
max_history_data_response_size
]
cont
=
cont_timestamps
[
nb_values
]
results
=
results
[:
self
.
max_history_data_response_size
]
results
=
results
[:
nb_values
]
return
results
,
cont
return
results
,
cont
def
_get_table_name
(
self
,
node_id
):
def
_get_table_name
(
self
,
node_id
):
...
@@ -241,7 +238,7 @@ class HistorySQLite(HistoryStorageInterface):
...
@@ -241,7 +238,7 @@ class HistorySQLite(HistoryStorageInterface):
start_time
=
end
.
isoformat
(
" "
)
start_time
=
end
.
isoformat
(
" "
)
end_time
=
start
.
isoformat
(
" "
)
end_time
=
start
.
isoformat
(
" "
)
if
nb_values
:
if
nb_values
:
limit
=
nb_values
+
1
# add 1 to the number of values for retrieving a continuation point
limit
=
nb_values
else
:
else
:
limit
=
-
1
# in SQLite a LIMIT of -1 returns all results
limit
=
-
1
# in SQLite a LIMIT of -1 returns all results
return
start_time
,
end_time
,
order
,
limit
return
start_time
,
end_time
,
order
,
limit
...
...
examples/client-example.py
View file @
af5a31c0
...
@@ -3,7 +3,6 @@ import logging
...
@@ -3,7 +3,6 @@ import logging
from
asyncua
import
Client
from
asyncua
import
Client
logging
.
basicConfig
(
level
=
logging
.
INFO
)
_logger
=
logging
.
getLogger
(
'asyncua'
)
_logger
=
logging
.
getLogger
(
'asyncua'
)
...
@@ -64,4 +63,5 @@ async def main():
...
@@ -64,4 +63,5 @@ async def main():
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
logging
.
basicConfig
(
level
=
logging
.
INFO
)
asyncio
.
run
(
main
())
asyncio
.
run
(
main
())
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