draegerwerk / sdc11073 Goto Github PK
View Code? Open in Web Editor NEWISO/IEEE 11073 SDC implementation for testing purposes and demonstration environments in python
License: MIT License
ISO/IEEE 11073 SDC implementation for testing purposes and demonstration environments in python
License: MIT License
Add templates for issues and pull requests
mk_scopes only creates a scope if a location is set
mk_scopes always creates a scope. If the location is not set, only that entry is omitted.
No response
3.9
all
2.0.0a1
No response
No response
In order to keep the release page a bit more readable, zip all unittest results into one folder
no alternative available
adapt github release workflow to zip all unittest results before adding to release
No response
For a master thesis, I want to implement an SDC-Serial-Port-Bridge in python. To achieve this, I want to subscribe to updates on the metrics, especially the action metrics. In my search in through the source code, I couldn't find an example for my problem.
After I created the SdcDevice
how do I subscribe to action metrics. All other metrics I know how to subscribe to on the provider/device side.
sdcDevice = SdcDevice(ws_discovery=myDiscovery,
my_uuid=my_uuid,
model=dpwsModel,
device=dpwsDevice,
deviceMdibContainer=my_mdib)
# start the local device and make it discoverable
sdcDevice.startAll()
Thanks for your help!
The following error occurred while sdc11073 was communicating with itself.
Traceback (most recent call last):
File "/tmp/venv/lib/python3.10/site-packages/sdc11073/sdcdevice/httpserver.py", line 165, in do_POST
response_xml_string = devices_dispatcher.on_post(self.path, self.headers, request)
File "/tmp/venv/lib/python3.10/site-packages/sdc11073/sdcdevice/httpserver.py", line 75, in on_post
return self.get_device_dispatcher(path).on_post(path, headers, request)
File "/tmp/venv/lib/python3.10/site-packages/sdc11073/sdcdevice/httpserver.py", line 106, in on_post
response = self._dispatchSoapRequest(path, headers, soapEnvelope)
File "/tmp/venv/lib/python3.10/site-packages/sdc11073/sdcdevice/httpserver.py", line 116, in _dispatchSoapRequest
return hostedService.dispatchSoapRequest( path, header, soapEnvelope)
File "/tmp/venv/lib/python3.10/site-packages/sdc11073/sdcdevice/sdcservicesimpl.py", line 144, in dispatchSoapRequest
response_envelope = super().dispatchSoapRequest(path, httpHeader, soapEnvelope)
File "/tmp/venv/lib/python3.10/site-packages/sdc11073/sdcdevice/sdcservicesimpl.py", line 72, in dispatchSoapRequest
returnedSoapEnvelope = fn(httpHeader, soapEnvelope)
File "/tmp/venv/lib/python3.10/site-packages/sdc11073/sdcdevice/sdcservicesimpl.py", line 163, in _onSubscribe
returnedSoapEnvelope = self._subscriptionsManager.onSubscribeRequest(httpHeader, soapEnvelope, self.epr)
File "/tmp/venv/lib/python3.10/site-packages/sdc11073/sdcdevice/subscriptionmgr.py", line 319, in onSubscribeRequest
s = _DevSubscription.fromSoapEnvelope(soapEnvelope, self._sslContext, acceptedEncodings,
File "/tmp/venv/lib/python3.10/site-packages/sdc11073/sdcdevice/subscriptionmgr.py", line 261, in fromSoapEnvelope
endToAddress = endToNode.xpath('wsa:Address/text()', namespaces=nsmap)[0]
IndexError: list index out of range
Found in version 1.1.22
fix issues found by linter
No response
No response
Currently, netifaces is always installed, even though it is not used when running on windows. It should instead be a conditional dependency which is only installed when not running on windows. See PEP508 for reference: https://www.python.org/dev/peps/pep-0508/
Implement the handling of the waveforms as a role provider
The documentation in sdc11073/ca is misleading, the folder isn't actually used for default certificates. Remove it or clarify the intended behavior if there is one.
Remove the "netifaces" dependency for platforms other than Windows (and thus entirely) to improve compatibility with newer/future CPython versions.
"netifaces" does not seem to officially support CPython versions >=3.10 and there are no build distributions available for those CPython versions on pypi, only a source distribution.
Move everything related to xml into a folder called xml
Instead of having base classes which raise an NotImplementedError
if a inherited class has not implemented a required method, use the abc
package to indicate that a class or method is abstract
in order to be independent of xml
, create separate classes for the data-models from biceps and for the xml stuff. Also, add a layer that translates between them.
Send a descriptor update after set_mdib
has been used
add an option to sdcclient
to use only encrypted communication or not. use an optional boolean flag for either
true
: enforce encryption and raise error if communication failedfalse
: do not allow encryption and raise error if communication failedNone
: try encrypted communication, then try unencrypted communication. if both fail, raise errorssl_context
is specified, take default ssl context generated by pythonIn line 62 of provider.py:
sdcDevice = sdc11073.sdcdevice.sdcdeviceimpl.PublishingSdcDevice(ws_discovery=....
should be (if not change within the library):
sdcDevice = sdc11073.sdcdevice.sdcdeviceimpl.SdcDevice(ws_discovery=...
Modern python packages use a pyproject.toml file.
Use flit as build system, because it is possible to get the version from a dynamic variable (useful when parsing from a tag)
[build-system]
requires = ["flit_core >=3.2"]
build-backend = "flit_core.buildapi"
we need the implementation for pm:CalibrationInfo/@time but it is currently a NotImplementedProperty
for version 1 (and 2)
sdc11073/src/sdc11073/mdib/statecontainers.py
Line 233 in ab41788
Move everything related to xml into a folder called xml
mkStateContainersforAllDescriptors does not update observables, so when loading an xml file containing an mdib to instantiate a device mdib, the observables get updated for states that are in the xml file, but not for those that are missing and getting generated by mkStateContainersforAllDescriptors.
This is an inconsistent behaviour.
Please make it consistent.
Hi! I am interested in using this repo to demonstrate transfer of data from a medical device (i.e. a pacemaker), however I noticed that the tutorial code only updates the 'consumer' with a state change that increments consistently. If you could point me in the direction of how to alter the tutorial so that it displays actual data sent from the 'provider' it would be greatly appreciated!
Also in line 62 of provider.py I noticed that with the refactored code the
sdcDevice = sdc11073.sdcdevice.sdcdeviceimpl.PublishingSdcDevice(...)
should be changed to
sdcDevice = sdc11073.sdcdevice.sdcdeviceimpl.SdcDevice(...)
Without the correction a 'module not found' error is thrown
Make the package async
complete by using the keywords async
and await
.
SdcClient._register_mdib (essential for initMdib) sets SdcClient._mdib in the following way:
self._mdib = None if mdib is None else weakref.ref(mdib)
This results in the SdcClient.mdib property to only return a previously set (non None) mdib for as long as there is a strong reference to the mdib somewhere, set by the application which is using sdc11073. When there is no such reference set by the application anymore the SdcClient.mdib might suddenly return None instead of the non None object that would have been returned previously, because the object referenced by SdcClient._mdib has been collected by the interpreters' garbage collector.
In addition all the checks (e.g. _canAcceptMdibVersion) that are bound to mdib observables are longer executed.
Please document this very well or change the behaviour so that the SdcClient does not loose it's mdib (reference) anymore.
The latter is the prefered solution.
Currently there are no releases on the repositories main page and the repository has no tags, but there are already multiple versions of sdc11073 released on pypi.
Although it is possible to associate a given whl file from pypi with a revision on GitHub through the information in the whl file itself, there is currently no reliable way of checking out the releases by only looking at the repository.
It would be nice and helpful to have the respective revisions associated with a version/release through git tags as well as to have releases on https://github.com/Draegerwerk/sdc11073/releases .
After setting up the pyproject.toml
file in #105 setup proper CI with the following components
Currently, the sdc11073 ReferenceTest-Device offers a ContainmentTreeService, but answers GetContainmentTree Requests with a SOAPFault: Receiver: not implemented.
This was observed when running SDCcc (7.0.1) against sdc11073 (version: b370b79, should be 1.1.25 I think).
NOTE: The same behaviour can be observed for GetDescriptor Requests.
While offering a ContainmentTreeService is optional (Biceps:R0119), a device offering a ContainmentTreeService must respond to GetContainmentTree- and GetDescriptor-Requests in a way conformant with the Requirements (f.i. Biceps:R5030, R5031, R5032, R5033, R5034, and R5035).
I would suggest to resolve this situation by either not offering a ContainmentTreeService or by implementing GetContainmentTree and GetDescriptor.
No response
No response
on branch Version_1.1.x
in sdc11073/sdcclient/subscription.py
and sdc11073/sdcdevice/httpserver.py
a single threaded http server seems to be implemented, but can not be easily activated, e.g. via changing the source code to set the globale variabe MULTITHREADED=False
when doing this, an AttributeError occurs, e.g.:
File "sdc11073\sdcclient\subscription.py", line 648, in stop
for thr in self.httpd.threads:
AttributeError: 'HTTPServer' object has no attribute 'threads'
instead of namespacehelper.domTag() one can also use namespacehelper.PM.tag(). Remove redundant functionality.
n.a.
No response
No response
setup linting for ci
Class AbstractOperationDescriptorContainer in sdc11073/mdib/descriptorcontainers.py have attribute _props being a list of attribute names of this class, but the attribute "AccessLevel" is not included in this list. This leads to the fact that method _sortedContainerProperties from file sdc11073/mdib/containerbase.py does not include attribute "AccessLevel" in the list of all container properties and method** _updateFromNode** does not read this attribute from the node. Therefore all operations in mdib have AccessLevel attribute with implied value = "Usr"
An integration job that I have running cannot start the examples/ReferenceTest/reference_device.py
anymore. Relevant log:
2023-04-20 09:15:12,290 - sdc.device.op_reg - INFO - register operation "SetContextStateOperation handle=opSetPatCtx operationTarget=PC.mds0"
2023-04-20 09:15:12,291 - sdc.device.MinimalProduct - INFO - there are no operations without handler.
2023-04-20 09:15:12,291 - sdc.device - INFO - starting services, addr = ['127.0.0.1']
2023-04-20 09:15:12,329 - sdc.device - INFO - serving Services on 127.0.0.1:41581
2023-04-20 09:15:12,332 - sdc.discover - INFO - publishing Service epr=urn:uuid:12345678-6f55-11ea-9697-123456789abc, instanceId=581591299 Xaddr=['https://127.0.0.1:41581/123456786f5511ea9697123456789abc'] scopes=sdc.ctxt.loc:/sdc.ctxt.loc.detail/theFacility%2F%2F%2FnoPoint%2F%2FcomfyBed?fac=theFacility&poc=noPoint&bed=comfyBed, sdc.cdc.type:///130535, sdc.mds.pkp:1.2.840.10004.20701.1.1 types={http://docs.oasis-open.org/ws-dd/ns/dpws/2009/01}Device, {http://standards.ieee.org/downloads/11073/11073-20702-2016}MedicalDevice
2023-04-20 09:15:12,332 - sdc.discover - INFO - sending hello on Service epr=urn:uuid:12345678-6f55-11ea-9697-123456789abc, instanceId=581591299
Xaddr=['https://127.0.0.1:41581/123456786f5511ea9697123456789abc']
scopes=sdc.ctxt.loc:/sdc.ctxt.loc.detail/theFacility%2F%2F%2FnoPoint%2F%2FcomfyBed?fac=theFacility&poc=noPoint&bed=comfyBed, sdc.cdc.type:///130535, sdc.mds.pkp:1.2.840.10004.20701.1.1
types={http://docs.oasis-open.org/ws-dd/ns/dpws/2009/01}Device, {http://standards.ieee.org/downloads/11073/11073-20702-2016}MedicalDevice
2023-04-20 09:15:12,333 - sdc.discover - DEBUG - addMulticastMessage: adding message Id urn:uuid:5992b67f-9185-4ee5-8d80-4f1138479698. delay=134.00
UUID for this device is 12345678-6f55-11ea-9697-123456789abc
location for this device is SdcLocation sdc.ctxt.loc:/sdc.ctxt.loc.detail/theFacility%2F%2F%2FnoPoint%2F%2FcomfyBed?fac=theFacility&poc=noPoint&bed=comfyBed
Traceback (most recent call last):
File "/home/runner/work/ri_11073_integration_test/ri_11073_integration_test/sdc11073_git/examples/ReferenceTest/reference_device.py", line 69, in <module>
patientDescriptorHandle = my_mdib.descriptions.nodeName.get(domTag('PatientContext'))[0].handle
File "/home/runner/work/ri_11073_integration_test/ri_11073_integration_test/sdc11073_git/src/sdc11073/multikey.py", line 160, in __getattr__
return self._idxDefs[name] # .indices
KeyError: 'nodeName'
The tag of msg:Descriptor gets changed according to xsi:type e.g. msg:Descriptor gets changed to pm:AlertCondition represented as {BICEPS_ParticipantModel}AlertCondition
This behaviour causes observers to not have access to the original data.
Edit: This especially applies to callbacks where a full report is given as a parameter.
use ipaddress
package for ipaddress handling
The current naming of sdcdevice
and sdcclient
is not representing the naming defined in biceps.
A device could be a provider and consumer at the same time, which the current naming makes it confusing. Therefore, rename
sdcdevice
to provider
sdcclient
to consumer
I need help including the OperatorDetail
in the OperatorContextState
of a sdc device.
Following the the example in tutorial/provider/
analogously, I have success creating an OperatorContextState
, e.g. I can set the Identification
attribute, however the OperatorDetail
attribute does not seem to be included.
This is how the state looks like when requested by a client:
<pm:State xsi:type="pm:OperatorContextState" DescriptorVersion="0" StateVersion="0" Handle="d03594cde8df49399ff120ddb4fd02a6" ContextAssociation="Assoc" BindingMdibVersion="2" BindingStartTime="1614273538793" DescriptorHandle="OP.mds0">
<pm:Identification Root="1.2.3" Extension="someOperatorContextState"/>
</pm:State>
This is the relevant code (like in the tutorial):
operator_context_state = mgr.getContextState(
operator_context_descriptor.handle
)
operator_context_state.ContextAssociation = "Assoc"
operator_context_state.Identification = [
pmtypes.InstanceIdentifier(
root="1.2.3", extensionString="someOperatorContextState"
)
]
# trying to set OperatorDetail
operator_detail = pmtypes.BaseDemographics(
givenname="someGivenName", familyname="someFamilyName"
)
operator_context_state.OperatorDetail = operator_detail
Thank you!
It's currently not possible to entirely disable plain connections using an sdc11073 client. Passing in an ssl context only enables tls, however, there are situations in which it might be desirable to entirely disallow plain traffic to and from an sdc provider. The same is probably true for the sdc11073 provider, but I haven't tested that yet.
Move everything related to xml into a folder called xml
The following error occurred in sdc11073.sdcclient.subscription .
File "venv/lib/python3.10/site-packages/sdc11073/sdcclient/sdcclientimpl.py", line 414, in stopAll
self._stopEventSink(closeAllConnections)
File "venv/lib/python3.10/site-packages/sdc11073/sdcclient/sdcclientimpl.py", line 535, in _stopEventSink
self._notificationsDispatcherThread.stop(closeAllConnections)
File "venv/lib/python3.10/site-packages/sdc11073/sdcclient/subscription.py", line 643, in stop
self.httpd.shutdown()
AttributeError: 'NoneType' object has no attribute 'shutdown'
Found in version 1.1.22
this would help eliminating duplicated log records in the console
this is also advisable to not add NullHandler to the library
see: https://docs.python.org/3.8/howto/logging.html#:~:text=than%20just%20%E2%80%98foo%E2%80%99.-,Note,-It%20is%20strongly
The following error occurrs quite frequently under load:
... - sdc.device - ERROR - Cannot start device, start event of http server not set.
Traceback (most recent call last):
File "venv\lib\site-packages\sdc11073\sdcdevice\sdcdeviceimpl.py", line 94, in startAll
return self._handler.startAll(startRealtimeSampleLoop, periodic_reports_interval, shared_http_server)
File "venv\lib\site-packages\sdc11073\sdcdevice\sdc_handlers.py", line 309, in startAll
self._startServices(shared_http_server)
File "venv\lib\site-packages\sdc11073\sdcdevice\sdc_handlers.py", line 274, in _startServices
raise RuntimeError('Cannot start device, start event of http server not set.')
RuntimeError: Cannot start device, start event of http server not set.
Fix it or provide a way of configuring the timeout that is being applied when waiting for started_evt.
Found in version 1.1.22
For RealTimeSampleArrayMetrics when updates arrive via EpisodicMetricReport then metricByHandle gets updated, when updates arrive via WaveformStream then waveformByHandle gets updates and when updates arrive via DescriptionModificationReport then waveformByHandle gets updated.
This means sometimes the obersvable is chosen by the extension of AbstractReport that contains the state and sometimes by the type of the state itself.
Please make it consistent.
py.typed
file. See PEP 561The following AttributeError might occur during handling of what is described in #142 .
...
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "venv\lib\site-packages\sdc11073\sdcdevice\sdcdeviceimpl.py", line 97, in stopAll
return self._handler.stopAll(closeAllConnections, sendSubscriptionEnd)
File "venv\lib\site-packages\sdc11073\sdcdevice\sdc_handlers.py", line 333, in stopAll
self._httpServerThread.stop(closeAllConnections)
File "venv\lib\site-packages\sdc11073\sdcdevice\httpserver.py", line 278, in stop
self.httpd.shutdown()
AttributeError: 'NoneType' object has no attribute 'shutdown'
Found in version 1.1.22
do not use https in device's location to determine if encrypted connection is possible, because https is just a convention
Add a limitation section to the README
file and add at least that
maybe raise an error if there are multiple ips or a handle changes during runtime
"get_ip_for_adapter" returning "None" and thus "self._my_ip_address" being "None" in the init of "WSDiscoverySingleAdapter" results in
AttributeError: 'str' object has no attribute 'nice_name'
Found in version 1.1.22
docs:
examples:
tutorial:
Setting a patient context state sometimes fails when I use a datetime.datetime object for the patient birth date that contains time values.
The problem is that the value of seconds sometimes resolves to a single digit, and it is not accepted by the XML schema.
Example:
import datetime as dt
from sdc11073 import isoduration
ninesecs = dt.datetime.now().replace(second=9)
birth_date_for_patient_context = ninesecs.isoformat()
print("This will be used for calling PatientContextStateContainer.setBirthDate: "
f"{birth_date_for_patient_context}")
birth_date_in_state_object = isoduration.parse_date_time(birth_date_for_patient_context)
birth_date_in_envelope = isoduration.date_time_string(birth_date_in_state_object)
print(f"This will be added to an XML: {birth_date_in_envelope}")
# Result:
# This will be used for PatientContextStateContainer.setBirthDate:
# 2021-10-27T13:25:09.544444
# This will be added to an XML: 2021-10-27T13:25:9.544444
Obviously, when firing the Set operation, it shows an error that "2021-10-27T13:25:9.544444 is not a valid tuple".
Move everything related to xml into a folder called xml
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.