pydaasiot 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. pydaasiot-0.2.0/.github/workflows/build-pypi.yml +100 -0
  2. pydaasiot-0.2.0/.github/workflows/build-testpypi.yml +100 -0
  3. pydaasiot-0.2.0/CMakeLists.txt +72 -0
  4. pydaasiot-0.2.0/LICENSE +0 -0
  5. pydaasiot-0.2.0/MANIFEST.in +7 -0
  6. pydaasiot-0.2.0/PKG-INFO +120 -0
  7. pydaasiot-0.2.0/README.md +104 -0
  8. pydaasiot-0.2.0/dist/pydaasiot-0.2.0-cp313-cp313-win_amd64.whl +0 -0
  9. pydaasiot-0.2.0/examples/DaaSChat.py +179 -0
  10. pydaasiot-0.2.0/examples/cli.py +136 -0
  11. pydaasiot-0.2.0/examples/receiver.py +43 -0
  12. pydaasiot-0.2.0/examples/sender.py +52 -0
  13. pydaasiot-0.2.0/examples/test.py +10 -0
  14. pydaasiot-0.2.0/include/daas.hpp +361 -0
  15. pydaasiot-0.2.0/include/daas_types.hpp +235 -0
  16. pydaasiot-0.2.0/include/daaswrapper.h +225 -0
  17. pydaasiot-0.2.0/include/net_utils.h +9 -0
  18. pydaasiot-0.2.0/lib/linux-gcc-x86_64/libdaas.a +0 -0
  19. pydaasiot-0.2.0/lib/windows-msvc-x64/daas.lib +0 -0
  20. pydaasiot-0.2.0/lib/windows-msvc-x64/daas_Debug.lib +0 -0
  21. pydaasiot-0.2.0/pyproject.toml +39 -0
  22. pydaasiot-0.2.0/src/cpp/daaswrapper.cpp +203 -0
  23. pydaasiot-0.2.0/src/cpp/net_utils.cpp +28 -0
  24. pydaasiot-0.2.0/src/cpp/pydaasiot.cpp +262 -0
  25. pydaasiot-0.2.0/src/pydaasiot/__init__.py +15 -0
  26. pydaasiot-0.2.0/third-parties/nlohmann/adl_serializer.hpp +55 -0
  27. pydaasiot-0.2.0/third-parties/nlohmann/byte_container_with_subtype.hpp +103 -0
  28. pydaasiot-0.2.0/third-parties/nlohmann/detail/abi_macros.hpp +111 -0
  29. pydaasiot-0.2.0/third-parties/nlohmann/detail/conversions/from_json.hpp +583 -0
  30. pydaasiot-0.2.0/third-parties/nlohmann/detail/conversions/to_chars.hpp +1118 -0
  31. pydaasiot-0.2.0/third-parties/nlohmann/detail/conversions/to_json.hpp +486 -0
  32. pydaasiot-0.2.0/third-parties/nlohmann/detail/exceptions.hpp +291 -0
  33. pydaasiot-0.2.0/third-parties/nlohmann/detail/hash.hpp +129 -0
  34. pydaasiot-0.2.0/third-parties/nlohmann/detail/input/binary_reader.hpp +3081 -0
  35. pydaasiot-0.2.0/third-parties/nlohmann/detail/input/input_adapters.hpp +550 -0
  36. pydaasiot-0.2.0/third-parties/nlohmann/detail/input/json_sax.hpp +986 -0
  37. pydaasiot-0.2.0/third-parties/nlohmann/detail/input/lexer.hpp +1643 -0
  38. pydaasiot-0.2.0/third-parties/nlohmann/detail/input/parser.hpp +536 -0
  39. pydaasiot-0.2.0/third-parties/nlohmann/detail/input/position_t.hpp +37 -0
  40. pydaasiot-0.2.0/third-parties/nlohmann/detail/iterators/internal_iterator.hpp +35 -0
  41. pydaasiot-0.2.0/third-parties/nlohmann/detail/iterators/iter_impl.hpp +760 -0
  42. pydaasiot-0.2.0/third-parties/nlohmann/detail/iterators/iteration_proxy.hpp +235 -0
  43. pydaasiot-0.2.0/third-parties/nlohmann/detail/iterators/iterator_traits.hpp +61 -0
  44. pydaasiot-0.2.0/third-parties/nlohmann/detail/iterators/json_reverse_iterator.hpp +130 -0
  45. pydaasiot-0.2.0/third-parties/nlohmann/detail/iterators/primitive_iterator.hpp +132 -0
  46. pydaasiot-0.2.0/third-parties/nlohmann/detail/json_custom_base_class.hpp +39 -0
  47. pydaasiot-0.2.0/third-parties/nlohmann/detail/json_pointer.hpp +988 -0
  48. pydaasiot-0.2.0/third-parties/nlohmann/detail/json_ref.hpp +78 -0
  49. pydaasiot-0.2.0/third-parties/nlohmann/detail/macro_scope.hpp +601 -0
  50. pydaasiot-0.2.0/third-parties/nlohmann/detail/macro_unscope.hpp +47 -0
  51. pydaasiot-0.2.0/third-parties/nlohmann/detail/meta/call_std/begin.hpp +17 -0
  52. pydaasiot-0.2.0/third-parties/nlohmann/detail/meta/call_std/end.hpp +17 -0
  53. pydaasiot-0.2.0/third-parties/nlohmann/detail/meta/cpp_future.hpp +171 -0
  54. pydaasiot-0.2.0/third-parties/nlohmann/detail/meta/detected.hpp +70 -0
  55. pydaasiot-0.2.0/third-parties/nlohmann/detail/meta/identity_tag.hpp +21 -0
  56. pydaasiot-0.2.0/third-parties/nlohmann/detail/meta/is_sax.hpp +159 -0
  57. pydaasiot-0.2.0/third-parties/nlohmann/detail/meta/std_fs.hpp +29 -0
  58. pydaasiot-0.2.0/third-parties/nlohmann/detail/meta/type_traits.hpp +821 -0
  59. pydaasiot-0.2.0/third-parties/nlohmann/detail/meta/void_t.hpp +24 -0
  60. pydaasiot-0.2.0/third-parties/nlohmann/detail/output/binary_writer.hpp +1863 -0
  61. pydaasiot-0.2.0/third-parties/nlohmann/detail/output/output_adapters.hpp +147 -0
  62. pydaasiot-0.2.0/third-parties/nlohmann/detail/output/serializer.hpp +988 -0
  63. pydaasiot-0.2.0/third-parties/nlohmann/detail/string_concat.hpp +146 -0
  64. pydaasiot-0.2.0/third-parties/nlohmann/detail/string_escape.hpp +72 -0
  65. pydaasiot-0.2.0/third-parties/nlohmann/detail/string_utils.hpp +37 -0
  66. pydaasiot-0.2.0/third-parties/nlohmann/detail/value_t.hpp +118 -0
  67. pydaasiot-0.2.0/third-parties/nlohmann/json.hpp +5319 -0
  68. pydaasiot-0.2.0/third-parties/nlohmann/json_fwd.hpp +75 -0
  69. pydaasiot-0.2.0/third-parties/nlohmann/ordered_map.hpp +359 -0
  70. pydaasiot-0.2.0/third-parties/nlohmann/thirdparty/hedley/hedley.hpp +2045 -0
  71. pydaasiot-0.2.0/third-parties/nlohmann/thirdparty/hedley/hedley_undef.hpp +158 -0
@@ -0,0 +1,100 @@
1
+ name: build-and-publish-pypi
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*.*.*"] # Esempio: v0.2.0
6
+ workflow_dispatch: # Avvio manuale dalla tab Actions
7
+
8
+ jobs:
9
+ build-wheels:
10
+ name: Build wheels (${{ matrix.os }})
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ matrix:
14
+ os: [ubuntu-22.04, windows-2022]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ with:
19
+ lfs: true
20
+
21
+ - name: Show SDK files (pre-build check)
22
+ shell: bash
23
+ run: |
24
+ echo "== include =="
25
+ ls -l include || true
26
+ echo "== lib/windows-msvc-x64 =="
27
+ ls -l lib/windows-msvc-x64 || true
28
+ echo "== lib/linux-gcc-x86_64 =="
29
+ ls -l lib/linux-gcc-x86_64 || true
30
+
31
+ - uses: actions/setup-python@v5
32
+ with:
33
+ python-version: "3.11"
34
+
35
+ - run: python -m pip install --upgrade pip cibuildwheel==2.*
36
+
37
+ - name: Build wheels
38
+ env:
39
+ CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-* cp313-*"
40
+ CIBW_SKIP: "*-win32 *-manylinux_i686 pp* *-musllinux_*"
41
+ CIBW_ARCHS_WINDOWS: "AMD64"
42
+ CIBW_ARCHS_LINUX: "x86_64"
43
+ CIBW_MANYLINUX_X86_64_IMAGE: "manylinux2014"
44
+ CIBW_BUILD_VERBOSITY: "3"
45
+ CIBW_ENVIRONMENT_WINDOWS: 'CMAKE_ARGS="-DDAAS_WIN_ROOT=lib/windows-msvc-x64 -DCMAKE_VERBOSE_MAKEFILE=ON" SKBUILD_VERBOSE=1'
46
+ CIBW_ENVIRONMENT_LINUX: 'CMAKE_ARGS="-DDAAS_LINUX_ROOT=lib/linux-gcc-x86_64 -DCMAKE_VERBOSE_MAKEFILE=ON" SKBUILD_VERBOSE=1'
47
+ run: cibuildwheel --output-dir wheelhouse
48
+
49
+ - uses: actions/upload-artifact@v4
50
+ with:
51
+ name: wheels-${{ matrix.os }}
52
+ path: wheelhouse/*.whl
53
+
54
+ sdist:
55
+ runs-on: ubuntu-22.04
56
+ steps:
57
+ - uses: actions/checkout@v4
58
+ with:
59
+ lfs: true
60
+
61
+ - uses: actions/setup-python@v5
62
+ with:
63
+ python-version: "3.11"
64
+
65
+ - run: python -m pip install --upgrade pip build
66
+
67
+ - name: Build sdist
68
+ run: python -m build --sdist
69
+
70
+ - uses: actions/upload-artifact@v4
71
+ with:
72
+ name: sdist
73
+ path: dist/*.tar.gz
74
+
75
+ publish-pypi:
76
+ needs: [build-wheels, sdist]
77
+ runs-on: ubuntu-22.04
78
+ steps:
79
+ - uses: actions/download-artifact@v4
80
+ with:
81
+ name: wheels-ubuntu-22.04
82
+ path: dist
83
+
84
+ - uses: actions/download-artifact@v4
85
+ with:
86
+ name: wheels-windows-2022
87
+ path: dist
88
+
89
+ - uses: actions/download-artifact@v4
90
+ with:
91
+ name: sdist
92
+ path: dist
93
+
94
+ - name: Upload to PyPI
95
+ env:
96
+ TWINE_USERNAME: __token__
97
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
98
+ run: |
99
+ python -m pip install --upgrade pip twine
100
+ twine upload dist/*
@@ -0,0 +1,100 @@
1
+ name: build-and-publish-testpypi
2
+
3
+ on:
4
+ push:
5
+ tags: ["pre*"] # Esempio: pre0.2.0
6
+ workflow_dispatch: # Avvio manuale dalla tab Actions
7
+
8
+ jobs:
9
+ build-wheels:
10
+ name: Build wheels (${{ matrix.os }})
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ matrix:
14
+ os: [ubuntu-22.04, windows-2022]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ with:
19
+ lfs: true # ok anche se non usi LFS
20
+
21
+ - name: Show SDK files (pre-build check)
22
+ shell: bash
23
+ run: |
24
+ echo "== include =="
25
+ ls -l include || true
26
+ echo "== lib/windows-msvc-x64 =="
27
+ ls -l lib/windows-msvc-x64 || true
28
+ echo "== lib/linux-gcc-x86_64 =="
29
+ ls -l lib/linux-gcc-x86_64 || true
30
+
31
+ - uses: actions/setup-python@v5
32
+ with:
33
+ python-version: "3.11"
34
+
35
+ - run: python -m pip install --upgrade pip cibuildwheel==2.*
36
+
37
+ - name: Build wheels
38
+ env:
39
+ CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-* cp313-*"
40
+ CIBW_SKIP: "*-win32 *-manylinux_i686 pp* *-musllinux_*"
41
+ CIBW_ARCHS_WINDOWS: "AMD64"
42
+ CIBW_ARCHS_LINUX: "x86_64"
43
+ CIBW_MANYLINUX_X86_64_IMAGE: "manylinux2014"
44
+ CIBW_BUILD_VERBOSITY: "3"
45
+ CIBW_ENVIRONMENT_WINDOWS: 'CMAKE_ARGS="-DDAAS_WIN_ROOT=lib/windows-msvc-x64 -DCMAKE_VERBOSE_MAKEFILE=ON" SKBUILD_VERBOSE=1'
46
+ CIBW_ENVIRONMENT_LINUX: 'CMAKE_ARGS="-DDAAS_LINUX_ROOT=lib/linux-gcc-x86_64 -DCMAKE_VERBOSE_MAKEFILE=ON" SKBUILD_VERBOSE=1'
47
+ run: cibuildwheel --output-dir wheelhouse
48
+
49
+ - uses: actions/upload-artifact@v4
50
+ with:
51
+ name: wheels-${{ matrix.os }}
52
+ path: wheelhouse/*.whl
53
+
54
+ sdist:
55
+ runs-on: ubuntu-22.04
56
+ steps:
57
+ - uses: actions/checkout@v4
58
+ with:
59
+ lfs: true
60
+
61
+ - uses: actions/setup-python@v5
62
+ with:
63
+ python-version: "3.11"
64
+
65
+ - run: python -m pip install --upgrade pip build
66
+
67
+ - name: Build sdist
68
+ run: python -m build --sdist
69
+
70
+ - uses: actions/upload-artifact@v4
71
+ with:
72
+ name: sdist
73
+ path: dist/*.tar.gz
74
+
75
+ publish-testpypi:
76
+ needs: [build-wheels, sdist]
77
+ runs-on: ubuntu-22.04
78
+ steps:
79
+ - uses: actions/download-artifact@v4
80
+ with:
81
+ name: wheels-ubuntu-22.04
82
+ path: dist
83
+
84
+ - uses: actions/download-artifact@v4
85
+ with:
86
+ name: wheels-windows-2022
87
+ path: dist
88
+
89
+ - uses: actions/download-artifact@v4
90
+ with:
91
+ name: sdist
92
+ path: dist
93
+
94
+ - name: Upload to TestPyPI
95
+ env:
96
+ TWINE_USERNAME: __token__
97
+ TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
98
+ run: |
99
+ python -m pip install --upgrade pip twine
100
+ twine upload --repository-url https://test.pypi.org/legacy/ dist/*
@@ -0,0 +1,72 @@
1
+ cmake_minimum_required(VERSION 3.20)
2
+ project(pydaasiot_native LANGUAGES CXX)
3
+
4
+ # Python & pybind11
5
+ find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)
6
+ find_package(pybind11 CONFIG REQUIRED)
7
+
8
+ set(CMAKE_CXX_STANDARD 17)
9
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
10
+
11
+ # Allinea la CRT alla runtime di Python su MSVC
12
+ if (MSVC)
13
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
14
+ endif()
15
+
16
+ # Percorsi include (globali o per-target; manteniamo semplici i globali)
17
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
18
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third-parties)
19
+
20
+ # Percorsi librerie (override da riga di comando se vuoi)
21
+ set(DAAS_WIN_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/lib/windows-msvc-x64" CACHE PATH "Path to Windows .lib")
22
+ set(DAAS_LINUX_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/lib/linux-gcc-x86_64" CACHE PATH "Path to Linux .a/.so")
23
+
24
+ # Normalizza eventuali backslash in input (Windows) -> sempre forward-slash
25
+ file(TO_CMAKE_PATH "${DAAS_WIN_ROOT}" DAAS_WIN_ROOT)
26
+ file(TO_CMAKE_PATH "${DAAS_LINUX_ROOT}" DAAS_LINUX_ROOT)
27
+
28
+ # Sorgenti C++ del binding
29
+ set(SRC_CPP
30
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/pydaasiot.cpp
31
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/daaswrapper.cpp
32
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/net_utils.cpp
33
+ )
34
+
35
+ # Modulo Python nativo: verrà installato come pydaasiot/_core.* (pyd/so)
36
+ pybind11_add_module(_core MODULE ${SRC_CPP})
37
+
38
+ # Su libreria statica, abilita PIC (utile su Linux)
39
+ set_target_properties(_core PROPERTIES POSITION_INDEPENDENT_CODE ON)
40
+
41
+ # Link a lib daas
42
+ if (WIN32)
43
+ target_link_libraries(_core PRIVATE
44
+ $<$<CONFIG:Release>:${DAAS_WIN_ROOT}/daas.lib>
45
+ $<$<CONFIG:Debug>:${DAAS_WIN_ROOT}/daas_Debug.lib>
46
+ ws2_32
47
+ )
48
+ elseif(UNIX)
49
+ # Preferisci statica se presente
50
+ if (EXISTS "${DAAS_LINUX_ROOT}/libdaas.a")
51
+ target_link_libraries(_core PRIVATE ${DAAS_LINUX_ROOT}/libdaas.a)
52
+ elseif (EXISTS "${DAAS_LINUX_ROOT}/libdaas.so")
53
+ target_link_libraries(_core PRIVATE ${DAAS_LINUX_ROOT}/libdaas.so)
54
+ else()
55
+ message(FATAL_ERROR "libdaas non trovata in ${DAAS_LINUX_ROOT}")
56
+ endif()
57
+
58
+ # BlueZ opzionale (se disponibile)
59
+ find_library(BLUEZ_LIB bluetooth)
60
+ if (BLUEZ_LIB)
61
+ target_link_libraries(_core PRIVATE ${BLUEZ_LIB})
62
+ endif()
63
+
64
+ # RPATH per caricare .so accanto al modulo
65
+ set_target_properties(_core PROPERTIES
66
+ INSTALL_RPATH "\$ORIGIN"
67
+ BUILD_WITH_INSTALL_RPATH ON
68
+ )
69
+ endif()
70
+
71
+ # Installa il modulo dentro il package Python
72
+ install(TARGETS _core DESTINATION pydaasiot)
File without changes
@@ -0,0 +1,7 @@
1
+ include README.md LICENSE
2
+ recursive-include include *.hpp *.h *.hh *.hxx
3
+ recursive-include third-parties *.hpp *.h *.txt *.md
4
+ prune docs
5
+ prune docs/html
6
+ exclude examples/*
7
+ prune examples
@@ -0,0 +1,120 @@
1
+ Metadata-Version: 2.2
2
+ Name: pydaasiot
3
+ Version: 0.2.0
4
+ Summary: Python bindings for DaaS-IoT (Windows + Linux manylinux).
5
+ Author-Email: Tuo Nome <you@example.com>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Programming Language :: Python :: Implementation :: CPython
8
+ Classifier: Programming Language :: C++
9
+ Classifier: Operating System :: Microsoft :: Windows
10
+ Classifier: Operating System :: POSIX :: Linux
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Project-URL: Homepage, https://github.com/tuo-org/pydaasiot
13
+ Project-URL: Issues, https://github.com/tuo-org/pydaasiot/issues
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+
17
+ # pydaasiot
18
+
19
+ [![PyPI version](https://img.shields.io/pypi/v/pydaasiot.svg)](https://pypi.org/project/pydaasiot/)
20
+ [![Python versions](https://img.shields.io/pypi/pyversions/pydaasiot.svg)](https://pypi.org/project/pydaasiot/)
21
+ [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux-blue.svg)](#-supported-platforms)
22
+ [![License](https://img.shields.io/pypi/l/pydaasiot.svg)](LICENSE)
23
+
24
+ **pydaasiot** are the official Python bindings for the **DaaS‑IoT SDK**.
25
+ They expose the full power of the Device‑as‑a‑Service paradigm directly into Python, making it easy to integrate IoT communication primitives, overlay networking and time synchronization into Python applications.
26
+
27
+ ---
28
+
29
+ ## 🌐 Overview
30
+
31
+ The **DaaS‑IoT SDK** is a high‑performance library designed for distributed IoT environments.
32
+ It provides an overlay communication model on top of TCP/IP, with support for multiple drivers and precise ATS (Accurate Time Synchronization) mechanisms.
33
+
34
+ The Python package `pydaasiot` allows developers and researchers to access these capabilities without writing C++ code, simplifying prototyping and integration into data pipelines, experiments and services.
35
+
36
+ ---
37
+
38
+ ## ✨ Main Features
39
+
40
+ - Initialization and management of **DaaS‑IoT nodes**.
41
+ - Add and configure network drivers (currently **INET4** and **Bluetooth**; more drivers such as Serial, USB, UART, MQTT are planned).
42
+ - Send and receive packets between devices.
43
+ - Retrieve and manage ATS synchronization parameters.
44
+ - Cross‑platform: distributed as prebuilt wheels for **Windows (MSVC)** and **Linux (manylinux2014)**.
45
+
46
+ ---
47
+
48
+ ## 🚀 Installation
49
+
50
+ Install from PyPI with:
51
+
52
+ ```bash
53
+ pip install pydaasiot
54
+ ```
55
+
56
+ Wheels are available for Python 3.9 – 3.12.
57
+ `pip` will automatically choose the correct wheel for your OS and Python version.
58
+
59
+ ---
60
+
61
+ ## 🧪 Quick Example
62
+
63
+ ```python
64
+ import pydaasiot
65
+
66
+ # Initialize a DaaS-IoT node
67
+ node = pydaasiot.Node()
68
+ node.init()
69
+
70
+ # Add a network driver (example: IPv4 link)
71
+ node.add_driver(2, "127.0.0.1:5000")
72
+
73
+ # Send a packet
74
+ node.push(b"Hello from Python")
75
+
76
+ # Receive packets (non-blocking)
77
+ packets = node.pull()
78
+ print("Received:", packets)
79
+
80
+ # Access ATS parameters
81
+ ats = node.get_sync_params()
82
+ print("ATS:", ats)
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 🖥️ Supported Platforms
88
+
89
+ - **Windows** (x86_64, MSVC)
90
+ - **Linux** (x86_64, manylinux2014)
91
+
92
+ macOS support is planned for a future release.
93
+
94
+ ---
95
+
96
+ ## 📚 Documentation
97
+
98
+ - Full SDK documentation: [GitHub repository](https://github.com/your-org/pydaasiot)
99
+ - Examples: available in the repository under `examples/` (not included in the PyPI package).
100
+
101
+ ---
102
+
103
+ ## 🔧 Development
104
+
105
+ Development is organized into feature branches for specific platforms.
106
+ The `main` branch is cross‑platform and serves as the source for official PyPI releases.
107
+ Tagged versions (`vX.Y.Z`) trigger CI pipelines that build wheels for Windows and Linux and publish them to PyPI.
108
+
109
+ ---
110
+
111
+ ## 🤝 Contributing
112
+
113
+ Contributions are welcome! Please use GitHub issues and pull requests to propose improvements or report bugs.
114
+
115
+ ---
116
+
117
+ ## 📄 License
118
+
119
+ Released under the terms of the **MIT License**.
120
+ See the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,104 @@
1
+ # pydaasiot
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/pydaasiot.svg)](https://pypi.org/project/pydaasiot/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/pydaasiot.svg)](https://pypi.org/project/pydaasiot/)
5
+ [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux-blue.svg)](#-supported-platforms)
6
+ [![License](https://img.shields.io/pypi/l/pydaasiot.svg)](LICENSE)
7
+
8
+ **pydaasiot** are the official Python bindings for the **DaaS‑IoT SDK**.
9
+ They expose the full power of the Device‑as‑a‑Service paradigm directly into Python, making it easy to integrate IoT communication primitives, overlay networking and time synchronization into Python applications.
10
+
11
+ ---
12
+
13
+ ## 🌐 Overview
14
+
15
+ The **DaaS‑IoT SDK** is a high‑performance library designed for distributed IoT environments.
16
+ It provides an overlay communication model on top of TCP/IP, with support for multiple drivers and precise ATS (Accurate Time Synchronization) mechanisms.
17
+
18
+ The Python package `pydaasiot` allows developers and researchers to access these capabilities without writing C++ code, simplifying prototyping and integration into data pipelines, experiments and services.
19
+
20
+ ---
21
+
22
+ ## ✨ Main Features
23
+
24
+ - Initialization and management of **DaaS‑IoT nodes**.
25
+ - Add and configure network drivers (currently **INET4** and **Bluetooth**; more drivers such as Serial, USB, UART, MQTT are planned).
26
+ - Send and receive packets between devices.
27
+ - Retrieve and manage ATS synchronization parameters.
28
+ - Cross‑platform: distributed as prebuilt wheels for **Windows (MSVC)** and **Linux (manylinux2014)**.
29
+
30
+ ---
31
+
32
+ ## 🚀 Installation
33
+
34
+ Install from PyPI with:
35
+
36
+ ```bash
37
+ pip install pydaasiot
38
+ ```
39
+
40
+ Wheels are available for Python 3.9 – 3.12.
41
+ `pip` will automatically choose the correct wheel for your OS and Python version.
42
+
43
+ ---
44
+
45
+ ## 🧪 Quick Example
46
+
47
+ ```python
48
+ import pydaasiot
49
+
50
+ # Initialize a DaaS-IoT node
51
+ node = pydaasiot.Node()
52
+ node.init()
53
+
54
+ # Add a network driver (example: IPv4 link)
55
+ node.add_driver(2, "127.0.0.1:5000")
56
+
57
+ # Send a packet
58
+ node.push(b"Hello from Python")
59
+
60
+ # Receive packets (non-blocking)
61
+ packets = node.pull()
62
+ print("Received:", packets)
63
+
64
+ # Access ATS parameters
65
+ ats = node.get_sync_params()
66
+ print("ATS:", ats)
67
+ ```
68
+
69
+ ---
70
+
71
+ ## 🖥️ Supported Platforms
72
+
73
+ - **Windows** (x86_64, MSVC)
74
+ - **Linux** (x86_64, manylinux2014)
75
+
76
+ macOS support is planned for a future release.
77
+
78
+ ---
79
+
80
+ ## 📚 Documentation
81
+
82
+ - Full SDK documentation: [GitHub repository](https://github.com/your-org/pydaasiot)
83
+ - Examples: available in the repository under `examples/` (not included in the PyPI package).
84
+
85
+ ---
86
+
87
+ ## 🔧 Development
88
+
89
+ Development is organized into feature branches for specific platforms.
90
+ The `main` branch is cross‑platform and serves as the source for official PyPI releases.
91
+ Tagged versions (`vX.Y.Z`) trigger CI pipelines that build wheels for Windows and Linux and publish them to PyPI.
92
+
93
+ ---
94
+
95
+ ## 🤝 Contributing
96
+
97
+ Contributions are welcome! Please use GitHub issues and pull requests to propose improvements or report bugs.
98
+
99
+ ---
100
+
101
+ ## 📄 License
102
+
103
+ Released under the terms of the **MIT License**.
104
+ See the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,179 @@
1
+ import pydaasiot
2
+ from pydaasiot import DDO, IDaasApiEvent, DaasWrapper
3
+
4
+ class HandlerBidirezionale(IDaasApiEvent):
5
+
6
+ def __init__(self, nodo):
7
+ super().__init__()
8
+ self.nodo = nodo
9
+
10
+ def ddoReceivedEvent(self, dimensione_payload, typeset, din_sorgente):
11
+ print(f"Messaggio ricevuto da: {din_sorgente}, dimensione: {dimensione_payload}, typeset: {typeset}")
12
+
13
+ result, ddo = self.nodo.wrapper.pull(din_sorgente)
14
+ print(f"DEBUG pull() -> result = {result} , ddo = {ddo}")
15
+
16
+ if result == pydaasiot.daas_error_t.ERROR_NONE and ddo is not None:
17
+
18
+ payload = ddo.getPayloadAsBinary()
19
+
20
+ try:
21
+ msg = payload.decode('utf-8')
22
+ print(f"Messaggio: {msg}")
23
+ except Exception:
24
+ print(f"Messaggio: {payload}")
25
+ else:
26
+ print(f"Pull non riuscito con errore {result}")
27
+
28
+ def dinAcceptedEvent(self, din):
29
+ print(f"DIN {din} accettato")
30
+
31
+
32
+ def nodeStateReceivedEvent(self, din): pass
33
+ def frisbeeReceivedEvent(self, din): pass
34
+ def atsSyncCompleted(self, din): pass
35
+ def frisbeeDperfCompleted(self, din, p, s): pass
36
+
37
+
38
+ class NodoBidirezionale:
39
+ def __init__(self, sid, din, ip_locale, porta_locale, din_remoto, ip_remoto,
40
+ porta_remota):
41
+
42
+ self.sid = sid
43
+ self.din = din
44
+ self.ip_locale = ip_locale
45
+ self.porta_locale = porta_locale
46
+ self.din_remoto = din_remoto
47
+ self.ip_remoto = ip_remoto
48
+ self.porta_remota = porta_remota
49
+
50
+ self.handler = HandlerBidirezionale(self)
51
+ self.wrapper = DaasWrapper("",self.handler)
52
+ self.handler.nodo = self
53
+ self.running = False
54
+
55
+ def chat_interattiva(self):
56
+ """Interfaccia chat interattiva"""
57
+ print("CHAT ATTIVA - Scrivi un messaggio per il nodo remoto")
58
+ print(" Scrivi: '!quit' per interrompere")
59
+ print(" Scrivi: '!status' per lo stato")
60
+
61
+ while self.running:
62
+ try:
63
+ messaggio = input("> ")
64
+
65
+ if not messaggio:
66
+ continue
67
+
68
+ if messaggio.lower() == '!quit':
69
+ break
70
+
71
+ if messaggio.lower() == '!status':
72
+ print(f"Nodo ativo - DIN: {self.din}")
73
+ continue
74
+
75
+ self.invia_messaggio(messaggio)
76
+ except KeyboardInterrupt:
77
+ break
78
+ except Exception as e:
79
+ print(f"Errore Input: {e}")
80
+
81
+ def inizializza_mio_nodo(self):
82
+ """Inizializzo nodo"""
83
+ print("Inizializzo nodo locale")
84
+
85
+ nodo = self.wrapper.doInit(self.sid, self.din)
86
+ if nodo != pydaasiot.daas_error_t.ERROR_NONE:
87
+ print("Errore inizializzazione")
88
+ return False
89
+ print("Nodo inizializzato")
90
+ return True
91
+
92
+ def configura_miei_driver(self):
93
+ print("Configuro Driver nodo locale")
94
+ uri_locale = f"{self.ip_locale}:{self.porta_locale}"
95
+ driver = self.wrapper.enableDriver(pydaasiot.link_t._LINK_INET4, uri_locale)
96
+ if driver != pydaasiot.daas_error_t.ERROR_NONE:
97
+ print("Errore Driver!")
98
+ return False
99
+ print("Driver configurati")
100
+ return True
101
+
102
+ def mappa_nodo_remoto(self):
103
+ uri_remoto = f"{self.ip_remoto}:{self.porta_remota}"
104
+ nodo_remoto = self.wrapper.map(self.din_remoto, pydaasiot.link_t._LINK_INET4,
105
+ uri_remoto)
106
+
107
+ if nodo_remoto != pydaasiot.daas_error_t.ERROR_NONE:
108
+ print("Errore mappatura nodo remoto")
109
+ return False
110
+ print("Mappatura nodo remoto completata")
111
+ return True
112
+
113
+ def invia_messaggio(self, messaggio):
114
+ ddo = DDO()
115
+ ddo.setOrigin(self.din)
116
+ ddo.setTypeset(1)
117
+ ddo.allocatePayload(len(messaggio))
118
+ ddo.appendPayloadData(messaggio.encode('utf-8'))
119
+
120
+
121
+ invio = self.wrapper.push(self.din_remoto, ddo)
122
+ if invio == 0:
123
+ print(f"Messaggio inviato a: {self.din_remoto}")
124
+ return True
125
+ else:
126
+ print("Invio messaggio non riuscito")
127
+ return False
128
+
129
+ def start(self):
130
+ self.running = True
131
+ avvio = self.wrapper.doPerform(pydaasiot.performs_mode_t.PERFORM_CORE_THREAD)
132
+ if avvio != pydaasiot.daas_error_t.ERROR_NONE:
133
+ print("Avvio non riuscito")
134
+ return False
135
+ print("Esecuzione nodo avviata")
136
+ return True
137
+
138
+ def stop(self):
139
+ self.running = False
140
+ self.wrapper.doEnd()
141
+ print("Esecuzione nodo arrestata")
142
+
143
+
144
+ def main():
145
+ SID = 100
146
+ MIO_DIN = int(input("Inserisci il tuo DIN: ").strip())
147
+ MIO_IP = input("Inserisci il tuo IP: ").strip()
148
+ MIA_PORTA = int(input("Inserisci la tua porta").strip())
149
+
150
+ DIN_REMOTO = int(input("Inserisci il DIN remoto").strip())
151
+ IP_REMOTO = input("Inserisci IP remoto").strip()
152
+ PORTA_REMOTA = int(input("Inserisci la porta remota").strip())
153
+
154
+ nodo = NodoBidirezionale(sid=SID, din=MIO_DIN, ip_locale=MIO_IP,
155
+ porta_locale=MIA_PORTA, din_remoto=DIN_REMOTO,
156
+ ip_remoto=IP_REMOTO,
157
+ porta_remota=PORTA_REMOTA)
158
+
159
+ if not nodo.inizializza_mio_nodo():
160
+ return
161
+
162
+ if not nodo.configura_miei_driver():
163
+ return
164
+
165
+ if not nodo.mappa_nodo_remoto():
166
+ return
167
+
168
+ if not nodo.start():
169
+ return
170
+
171
+ try:
172
+ nodo.chat_interattiva()
173
+ except KeyboardInterrupt:
174
+ print("Interruzione da tastiera...")
175
+ finally:
176
+ nodo.stop()
177
+
178
+ if __name__ == "__main__":
179
+ main()