dapps 0.0.1__tar.gz → 0.0.2__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.
- dapps-0.0.2/.github/workflows/tag-and-release.yml +146 -0
- {dapps-0.0.1 → dapps-0.0.2}/PKG-INFO +1 -1
- dapps-0.0.2/VERSION +1 -0
- {dapps-0.0.1 → dapps-0.0.2}/docs/gui_uml.txt +1 -3
- {dapps-0.0.1 → dapps-0.0.2}/examples/spectrum_dapp.py +11 -3
- {dapps-0.0.1 → dapps-0.0.2}/src/spectrum/spectrum_dapp.py +14 -22
- {dapps-0.0.1 → dapps-0.0.2}/src/visualization/dashboard.py +11 -3
- {dapps-0.0.1 → dapps-0.0.2}/src/visualization/templates/index.html +20 -1
- dapps-0.0.1/.github/workflows/release.yml +0 -121
- dapps-0.0.1/.github/workflows/tag-on-version-change.yml +0 -49
- dapps-0.0.1/VERSION +0 -1
- {dapps-0.0.1 → dapps-0.0.2}/.github/workflows/mirror.yml +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/.gitignore +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/LICENSE +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/MANIFEST.in +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/README.md +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/docker/Dockerfile +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/docker/build.sh +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/docs/dapp_uml.txt +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/e3protocol/README.md +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/e3protocol/build_asn.sh +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/e3protocol/client/client.c +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/e3protocol/dump_packets.sh +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/e3protocol/server/server.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/e3protocol/wrapper/e3.c +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/e3protocol/wrapper/e3.h +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/pyproject.toml +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/dapp/__init__.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/dapp/dapp.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/e3interface/__init__.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/e3interface/defs/e3.asn +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/e3interface/e3_connector.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/e3interface/e3_interface.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/e3interface/e3_logging.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/spectrum/__init__.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/visualization/__init__.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/visualization/energy.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/visualization/grafana.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/visualization/influx.py +0 -0
- {dapps-0.0.1 → dapps-0.0.2}/src/visualization/iq.py +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
name: Tag and Publish dApp package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
create-tag:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
outputs:
|
|
12
|
+
version: ${{ steps.set_version.outputs.version }}
|
|
13
|
+
tag_created: ${{ steps.set_output.outputs.tag_created }}
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout repository
|
|
16
|
+
uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 0 # Ensure we fetch all tags
|
|
19
|
+
|
|
20
|
+
- name: Read VERSION file
|
|
21
|
+
id: get_version
|
|
22
|
+
run: |
|
|
23
|
+
version=$(cat VERSION | tr -d '[:space:]')
|
|
24
|
+
echo "version=$version" >> $GITHUB_OUTPUT
|
|
25
|
+
|
|
26
|
+
- name: Check if tag exists
|
|
27
|
+
id: check_tag
|
|
28
|
+
run: |
|
|
29
|
+
if git rev-parse "refs/tags/${{ steps.get_version.outputs.version }}" >/dev/null 2>&1; then
|
|
30
|
+
echo "exists=true" >> $GITHUB_OUTPUT
|
|
31
|
+
else
|
|
32
|
+
echo "exists=false" >> $GITHUB_OUTPUT
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
- name: Create and push tag
|
|
36
|
+
if: steps.check_tag.outputs.exists == 'false'
|
|
37
|
+
id: create_push_tag
|
|
38
|
+
run: |
|
|
39
|
+
git tag ${{ steps.get_version.outputs.version }}
|
|
40
|
+
git push origin ${{ steps.get_version.outputs.version }}
|
|
41
|
+
|
|
42
|
+
- name: Set tag_created output
|
|
43
|
+
id: set_output
|
|
44
|
+
run: |
|
|
45
|
+
if [ "${{ steps.check_tag.outputs.exists }}" = "false" ]; then
|
|
46
|
+
echo "tag_created=true" >> $GITHUB_OUTPUT
|
|
47
|
+
else
|
|
48
|
+
echo "tag_created=false" >> $GITHUB_OUTPUT
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
- name: Set version output
|
|
52
|
+
id: set_version
|
|
53
|
+
run: |
|
|
54
|
+
echo "version=${{ steps.get_version.outputs.version }}" >> $GITHUB_OUTPUT
|
|
55
|
+
|
|
56
|
+
build:
|
|
57
|
+
name: Build distribution 📦
|
|
58
|
+
runs-on: ubuntu-latest
|
|
59
|
+
needs: create-tag
|
|
60
|
+
if: ${{ needs.create-tag.outputs.tag_created == 'true' && github.repository == 'wineslab/dApp-library' }}
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v4
|
|
63
|
+
with:
|
|
64
|
+
persist-credentials: false
|
|
65
|
+
- name: Set up Python
|
|
66
|
+
uses: actions/setup-python@v5
|
|
67
|
+
with:
|
|
68
|
+
python-version: "3.8"
|
|
69
|
+
- name: Install pypa/build
|
|
70
|
+
run: python3 -m pip install build --user
|
|
71
|
+
- name: Build a binary wheel and a source tarball
|
|
72
|
+
run: python3 -m build
|
|
73
|
+
- name: Store the distribution packages
|
|
74
|
+
uses: actions/upload-artifact@v4
|
|
75
|
+
with:
|
|
76
|
+
name: python-package-distributions
|
|
77
|
+
path: dist/
|
|
78
|
+
|
|
79
|
+
publish-to-pypi:
|
|
80
|
+
name: Publish to PyPI
|
|
81
|
+
needs: build
|
|
82
|
+
runs-on: ubuntu-latest
|
|
83
|
+
if: ${{ needs.create-tag.outputs.tag_created == 'true' && github.repository == 'wineslab/dApp-library' }}
|
|
84
|
+
environment:
|
|
85
|
+
name: pypi
|
|
86
|
+
url: https://pypi.org/p/dapps
|
|
87
|
+
permissions:
|
|
88
|
+
id-token: write
|
|
89
|
+
steps:
|
|
90
|
+
- name: Download all the dists
|
|
91
|
+
uses: actions/download-artifact@v4
|
|
92
|
+
with:
|
|
93
|
+
name: python-package-distributions
|
|
94
|
+
path: dist/
|
|
95
|
+
- name: Publish distribution 📦 to PyPI
|
|
96
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
97
|
+
|
|
98
|
+
github-release:
|
|
99
|
+
name: Sign packages with Sigstore and upload them to GitHub Release
|
|
100
|
+
needs: publish-to-pypi
|
|
101
|
+
runs-on: ubuntu-latest
|
|
102
|
+
if: ${{ needs.create-tag.outputs.tag_created == 'true' && github.repository == 'wineslab/dApp-library' }}
|
|
103
|
+
permissions:
|
|
104
|
+
contents: write
|
|
105
|
+
id-token: write
|
|
106
|
+
steps:
|
|
107
|
+
- name: Download all the dists
|
|
108
|
+
uses: actions/download-artifact@v4
|
|
109
|
+
with:
|
|
110
|
+
name: python-package-distributions
|
|
111
|
+
path: dist/
|
|
112
|
+
- name: Sign the dists with Sigstore
|
|
113
|
+
uses: sigstore/gh-action-sigstore-python@v3.0.0
|
|
114
|
+
with:
|
|
115
|
+
inputs: |
|
|
116
|
+
./dist/*.tar.gz
|
|
117
|
+
./dist/*.whl
|
|
118
|
+
- name: Create GitHub Release
|
|
119
|
+
env:
|
|
120
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
121
|
+
run: gh release create ${{ needs.create-tag.outputs.version }} --repo ${{ github.repository }} --notes ""
|
|
122
|
+
- name: Upload artifact signatures to GitHub Release
|
|
123
|
+
env:
|
|
124
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
125
|
+
run: gh release upload ${{ needs.create-tag.outputs.version }} dist/** --repo ${{ github.repository }}
|
|
126
|
+
|
|
127
|
+
publish-to-testpypi:
|
|
128
|
+
name: Publish to TestPyPI
|
|
129
|
+
needs: build
|
|
130
|
+
runs-on: ubuntu-latest
|
|
131
|
+
if: ${{ needs.create-tag.outputs.tag_created == 'true' && github.repository == 'wineslab/dApp-library' }}
|
|
132
|
+
environment:
|
|
133
|
+
name: testpypi
|
|
134
|
+
url: https://test.pypi.org/p/dapps
|
|
135
|
+
permissions:
|
|
136
|
+
id-token: write
|
|
137
|
+
steps:
|
|
138
|
+
- name: Download all the dists
|
|
139
|
+
uses: actions/download-artifact@v4
|
|
140
|
+
with:
|
|
141
|
+
name: python-package-distributions
|
|
142
|
+
path: dist/
|
|
143
|
+
- name: Publish distribution 📦 to TestPyPI
|
|
144
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
145
|
+
with:
|
|
146
|
+
repository-url: https://test.pypi.org/legacy/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dapps
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Summary: A library for creating and connecting dApps to Open RAN units.
|
|
5
5
|
Project-URL: Homepage, https://openrangym.com/ran-frameworks/dapps
|
|
6
6
|
Project-URL: Package, https://pypi.org/project/dapps/
|
dapps-0.0.2/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.2
|
|
@@ -34,7 +34,7 @@ class IQPlotter {
|
|
|
34
34
|
+ process_iq_data(iq_data)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
class
|
|
37
|
+
class Dashboard {
|
|
38
38
|
-- Attributes --
|
|
39
39
|
- BUFFER_SIZE : int
|
|
40
40
|
- iq_size : int
|
|
@@ -49,6 +49,4 @@ class DemoGui {
|
|
|
49
49
|
+ stop()
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
DemoGui --> IQPlotter : "contains"
|
|
53
|
-
DemoGui --> EnergyPlotter : "contains"
|
|
54
52
|
@enduml
|
|
@@ -23,10 +23,18 @@ def stop_program(time_to_wait, dapp: SpectrumSharingDApp):
|
|
|
23
23
|
def main(args, time_to_wait: float = 60.0):
|
|
24
24
|
# with open(f"{LOG_DIR}/busy.txt", "w") as f:
|
|
25
25
|
# f.close()
|
|
26
|
-
|
|
27
|
-
dapp = SpectrumSharingDApp(ota=args.ota, save_iqs=args.save_iqs, control=args.control, link=args.link, transport=args.transport,
|
|
28
|
-
energyGui=args.energy_gui, iqPlotterGui=args.iq_plotter_gui, demoGui=args.demo_gui)
|
|
29
26
|
|
|
27
|
+
if args.ota:
|
|
28
|
+
print(f'Using OTA configuration')
|
|
29
|
+
noise_floor_threshold = 20 # this really depends on the RF conditions and should be carefully calibrated
|
|
30
|
+
else: # Colosseum
|
|
31
|
+
print(f'Using Colosseum configuration')
|
|
32
|
+
noise_floor_threshold = 53
|
|
33
|
+
|
|
34
|
+
print(f'Threshold {noise_floor_threshold}')
|
|
35
|
+
|
|
36
|
+
dapp = SpectrumSharingDApp(noise_floor_threshold=noise_floor_threshold, save_iqs=args.save_iqs, control=args.control, link=args.link, transport=args.transport,
|
|
37
|
+
energyGui=args.energy_gui, iqPlotterGui=args.iq_plotter_gui, dashboard=args.demo_gui)
|
|
30
38
|
dapp.setup_connection()
|
|
31
39
|
|
|
32
40
|
if args.timed:
|
|
@@ -25,7 +25,7 @@ class SpectrumSharingDApp(DApp):
|
|
|
25
25
|
# Noise floor threshold needs to be calibrated
|
|
26
26
|
# We receive the symbols and average them over some frames, and do thresholding.
|
|
27
27
|
|
|
28
|
-
def __init__(self, id: int = 1,
|
|
28
|
+
def __init__(self, id: int = 1, noise_floor_threshold: int = 53, save_iqs: bool = False, control: bool = False, link: str = 'posix', transport:str = 'uds', **kwargs):
|
|
29
29
|
super().__init__(link=link, transport=transport, **kwargs)
|
|
30
30
|
|
|
31
31
|
self.bw = 40.08e6 # Bandwidth in Hz
|
|
@@ -35,14 +35,7 @@ class SpectrumSharingDApp(DApp):
|
|
|
35
35
|
self.prb_thrs = 75 # This avoids blacklisting PRBs where the BWP is scheduled (it’s a workaround bc the UE and gNB would not be able to communicate anymore, a cleaner fix is to move the BWP if needed or things like that)
|
|
36
36
|
self.FFT_SIZE = 1536
|
|
37
37
|
self.Average_over_frames = 63
|
|
38
|
-
|
|
39
|
-
if ota:
|
|
40
|
-
dapp_logger.info(f'Using OTA configuration')
|
|
41
|
-
self.Noise_floor_threshold = 20 # this really depends on the RF conditions and should be carefully calibrated
|
|
42
|
-
else: # Colosseum
|
|
43
|
-
dapp_logger.info(f'Using Colosseum configuration')
|
|
44
|
-
self.Noise_floor_threshold = 53
|
|
45
|
-
|
|
38
|
+
self.noise_floor_threshold = noise_floor_threshold
|
|
46
39
|
self.save_iqs = save_iqs
|
|
47
40
|
self.e3_interface.add_callback(self.get_iqs_from_ran)
|
|
48
41
|
if self.save_iqs:
|
|
@@ -54,7 +47,7 @@ class SpectrumSharingDApp(DApp):
|
|
|
54
47
|
|
|
55
48
|
self.energyGui = kwargs.get('energyGui', False)
|
|
56
49
|
self.iqPlotterGui = kwargs.get('iqPlotterGui', False)
|
|
57
|
-
self.
|
|
50
|
+
self.dashboard = kwargs.get('dashboard', False)
|
|
58
51
|
|
|
59
52
|
self.control_count = 1
|
|
60
53
|
self.abs_iq_av = np.zeros(self.FFT_SIZE)
|
|
@@ -70,11 +63,12 @@ class SpectrumSharingDApp(DApp):
|
|
|
70
63
|
iq_size = self.FFT_SIZE * 2 # double the size of ofdm_symbol_size since real and imaginary parts are interleaved
|
|
71
64
|
self.iqPlotter = IQPlotter(buffer_size=500, iq_size=iq_size, bw=self.bw, center_freq=self.center_freq)
|
|
72
65
|
|
|
73
|
-
if self.
|
|
74
|
-
from visualization.dashboard import
|
|
66
|
+
if self.dashboard:
|
|
67
|
+
from visualization.dashboard import Dashboard
|
|
75
68
|
self.demo_queue = multiprocessing.Queue()
|
|
76
69
|
iq_size = self.FFT_SIZE * 2 # double the size of ofdm_symbol_size since real and imaginary parts are interleaved
|
|
77
|
-
|
|
70
|
+
classifier = kwargs.get('classifier', None)
|
|
71
|
+
self.demo = Dashboard(buffer_size=100, iq_size=iq_size, classifier=classifier)
|
|
78
72
|
|
|
79
73
|
def get_iqs_from_ran(self, data):
|
|
80
74
|
dapp_logger.debug(f'Triggered callback')
|
|
@@ -93,7 +87,7 @@ class SpectrumSharingDApp(DApp):
|
|
|
93
87
|
if self.iqPlotterGui:
|
|
94
88
|
self.iq_queue.put(iq_arr)
|
|
95
89
|
|
|
96
|
-
if self.
|
|
90
|
+
if self.dashboard:
|
|
97
91
|
self.demo_queue.put(("iq_data", iq_arr))
|
|
98
92
|
|
|
99
93
|
if self.control:
|
|
@@ -106,9 +100,6 @@ class SpectrumSharingDApp(DApp):
|
|
|
106
100
|
self.control_count += 1
|
|
107
101
|
dapp_logger.debug(f"Control count is: {self.control_count}")
|
|
108
102
|
|
|
109
|
-
if self.iqPlotterGui:
|
|
110
|
-
self.iq_queue.put(iq_arr)
|
|
111
|
-
|
|
112
103
|
if self.control_count == self.Average_over_frames:
|
|
113
104
|
abs_iq_av_db = 20 * np.log10(1 + (self.abs_iq_av/(self.Average_over_frames)))
|
|
114
105
|
abs_iq_av_db_offset_correct = np.append(abs_iq_av_db[self.First_carrier_offset:self.FFT_SIZE],abs_iq_av_db[0:self.First_carrier_offset])
|
|
@@ -119,10 +110,9 @@ class SpectrumSharingDApp(DApp):
|
|
|
119
110
|
# last_5_max_abs_iq_av_db_offset_correct = np.sort(abs_iq_av_db_offset_correct)[-20:]
|
|
120
111
|
# dapp_logger.info(f'Last 20 max values (abs_iq_av_db_offset_correct): {last_5_max_abs_iq_av_db_offset_correct}')
|
|
121
112
|
|
|
122
|
-
|
|
123
113
|
# PRB blocking based on the noise floor threshold
|
|
124
114
|
f_ind = np.arange(self.FFT_SIZE)
|
|
125
|
-
blklist_sub_carrier = f_ind[abs_iq_av_db_offset_correct > self.
|
|
115
|
+
blklist_sub_carrier = f_ind[abs_iq_av_db_offset_correct > self.noise_floor_threshold]
|
|
126
116
|
np.sort(blklist_sub_carrier)
|
|
127
117
|
dapp_logger.info(f'blklist_sub_carrier: {blklist_sub_carrier}')
|
|
128
118
|
prb_blk_list = np.unique((np.floor(blklist_sub_carrier/self.Num_car_prb))).astype(np.uint16)
|
|
@@ -143,7 +133,7 @@ class SpectrumSharingDApp(DApp):
|
|
|
143
133
|
if self.energyGui:
|
|
144
134
|
self.sig_queue.put(abs_iq_av_db)
|
|
145
135
|
|
|
146
|
-
if self.
|
|
136
|
+
if self.dashboard:
|
|
147
137
|
self.demo_queue.put(("prb_list", prb_blk_list))
|
|
148
138
|
|
|
149
139
|
# Reset the variables
|
|
@@ -154,10 +144,12 @@ class SpectrumSharingDApp(DApp):
|
|
|
154
144
|
if self.energyGui:
|
|
155
145
|
abs_iq_av_db = self.sig_queue.get()
|
|
156
146
|
self.energyPlotter.process_iq_data(abs_iq_av_db)
|
|
147
|
+
|
|
157
148
|
if self.iqPlotterGui:
|
|
158
149
|
iq_data = self.iq_queue.get()
|
|
159
150
|
self.iqPlotter.process_iq_data(iq_data)
|
|
160
|
-
|
|
151
|
+
|
|
152
|
+
if self.dashboard:
|
|
161
153
|
message = self.demo_queue.get()
|
|
162
154
|
self.demo.process_iq_data(message)
|
|
163
155
|
|
|
@@ -165,5 +157,5 @@ class SpectrumSharingDApp(DApp):
|
|
|
165
157
|
if self.save_iqs:
|
|
166
158
|
self.iq_save_file.close()
|
|
167
159
|
|
|
168
|
-
if self.
|
|
160
|
+
if self.dashboard:
|
|
169
161
|
self.demo.stop()
|
|
@@ -13,8 +13,8 @@ except ModuleNotFoundError:
|
|
|
13
13
|
exit(-1)
|
|
14
14
|
import numpy as np
|
|
15
15
|
|
|
16
|
-
class
|
|
17
|
-
def __init__(self, buffer_size=100, iq_size=1536, bw=46.08e6, center_freq=3.6192e9):
|
|
16
|
+
class Dashboard:
|
|
17
|
+
def __init__(self, buffer_size=100, iq_size=1536, bw=46.08e6, center_freq=3.6192e9, classifier=None):
|
|
18
18
|
# TODO double check killing conditions
|
|
19
19
|
# Flask app setup
|
|
20
20
|
self.app = Flask(__name__)
|
|
@@ -30,6 +30,8 @@ class DemoGui:
|
|
|
30
30
|
# Route setup
|
|
31
31
|
self.app.add_url_rule("/", view_func=self.index)
|
|
32
32
|
|
|
33
|
+
self.classifier = classifier if classifier is not None else None
|
|
34
|
+
|
|
33
35
|
# SocketIO event handlers
|
|
34
36
|
self.socketio.on_event("connect", self.handle_initial_connection)
|
|
35
37
|
self._initialize_plot()
|
|
@@ -63,6 +65,7 @@ class DemoGui:
|
|
|
63
65
|
data_buffer = {
|
|
64
66
|
"magnitude": np.zeros((self.BUFFER_SIZE, iqs_to_show)).tolist(),
|
|
65
67
|
"num_prbs": num_prbs,
|
|
68
|
+
"predicted_label": self.classifier is not None
|
|
66
69
|
}
|
|
67
70
|
self.socketio.emit("initialize_plot", data_buffer)
|
|
68
71
|
|
|
@@ -88,6 +91,11 @@ class DemoGui:
|
|
|
88
91
|
if self.sampling_counter >= self.sampling_threshold:
|
|
89
92
|
magnitude_dB = self._process_iq_data(iq_data)[::-1].tolist() # visualization processing is delegated to client
|
|
90
93
|
self.socketio.emit("update_plot", {"magnitude": magnitude_dB})
|
|
94
|
+
|
|
95
|
+
if self.classifier:
|
|
96
|
+
label = self.classifier.predict(iq_data)
|
|
97
|
+
self.socketio.emit("update_plot", {"predicted_label": label})
|
|
98
|
+
|
|
91
99
|
self.sampling_counter = 0
|
|
92
100
|
|
|
93
101
|
elif plot == "prb_list":
|
|
@@ -101,4 +109,4 @@ class DemoGui:
|
|
|
101
109
|
self.run_thread.join()
|
|
102
110
|
|
|
103
111
|
if __name__ == "__main__":
|
|
104
|
-
server_app =
|
|
112
|
+
server_app = Dashboard()
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
<body>
|
|
12
12
|
<div id="prbs"></div>
|
|
13
13
|
<div id="magnitude"></div>
|
|
14
|
+
<div id="predicted_label"></div>
|
|
14
15
|
|
|
15
16
|
<script>
|
|
16
17
|
var waterfall = [{
|
|
@@ -22,7 +23,7 @@
|
|
|
22
23
|
var waterfallLayout = {
|
|
23
24
|
title: "Magnitude of the Sensed Spectrum",
|
|
24
25
|
xaxis: {
|
|
25
|
-
title: "OFDM
|
|
26
|
+
title: "Subcarriers of the OFDM Symbol"
|
|
26
27
|
},
|
|
27
28
|
yaxis: {
|
|
28
29
|
title: "Time samples",
|
|
@@ -152,8 +153,18 @@
|
|
|
152
153
|
}
|
|
153
154
|
};
|
|
154
155
|
|
|
156
|
+
var classifierLayout = {
|
|
157
|
+
title: {
|
|
158
|
+
text: "Predicted Label: N/A",
|
|
159
|
+
font: { size: 24 }
|
|
160
|
+
},
|
|
161
|
+
xaxis: { visible: false },
|
|
162
|
+
yaxis: { visible: false }
|
|
163
|
+
};
|
|
164
|
+
|
|
155
165
|
var waterfall_buffer;
|
|
156
166
|
var prbs_buffer;
|
|
167
|
+
var predictedLabel;
|
|
157
168
|
|
|
158
169
|
var socket = io.connect('http://' + document.domain + ':' + location.port);
|
|
159
170
|
socket.on('initialize_plot', function (data) {
|
|
@@ -163,6 +174,9 @@
|
|
|
163
174
|
prbs[0].z = prbs_buffer;
|
|
164
175
|
Plotly.newPlot('magnitude', waterfall, waterfallLayout);
|
|
165
176
|
Plotly.newPlot('prbs', prbs, prbsLayout);
|
|
177
|
+
if(data.predicted_label){
|
|
178
|
+
Plotly.newPlot("predicted_label", [], classifierLayout);
|
|
179
|
+
}
|
|
166
180
|
});
|
|
167
181
|
|
|
168
182
|
socket.on('update_plot', function (data) {
|
|
@@ -184,6 +198,11 @@
|
|
|
184
198
|
prbs_buffer[0].fill(0);
|
|
185
199
|
data.prb_list.forEach(index => prbs_buffer[0][index] = 1);
|
|
186
200
|
Plotly.restyle('prbs', { z: [prbs_buffer] });
|
|
201
|
+
} else if ('predicted_label' in data) {
|
|
202
|
+
console.log("Predicted label is: ", data.predicted_label);
|
|
203
|
+
Plotly.relayout('predicted_label', {
|
|
204
|
+
'title.text': `Predicted Label: ${data.predicted_label}`
|
|
205
|
+
});
|
|
187
206
|
} else {
|
|
188
207
|
console.error('Error unknown values in data ', data);
|
|
189
208
|
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
name: Publish dApp package to PyPI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- "*"
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
build:
|
|
10
|
-
name: Build distribution 📦
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
if: github.repository == 'wineslab/dApp-library'
|
|
13
|
-
|
|
14
|
-
steps:
|
|
15
|
-
- uses: actions/checkout@v4
|
|
16
|
-
with:
|
|
17
|
-
persist-credentials: false
|
|
18
|
-
- name: Set up Python
|
|
19
|
-
uses: actions/setup-python@v5
|
|
20
|
-
with:
|
|
21
|
-
python-version: "3.8"
|
|
22
|
-
- name: Install pypa/build
|
|
23
|
-
run: >-
|
|
24
|
-
python3 -m
|
|
25
|
-
pip install
|
|
26
|
-
build
|
|
27
|
-
--user
|
|
28
|
-
- name: Build a binary wheel and a source tarball
|
|
29
|
-
run: python3 -m build
|
|
30
|
-
- name: Store the distribution packages
|
|
31
|
-
uses: actions/upload-artifact@v4
|
|
32
|
-
with:
|
|
33
|
-
name: python-package-distributions
|
|
34
|
-
path: dist/
|
|
35
|
-
|
|
36
|
-
publish-to-pypi:
|
|
37
|
-
name: >-
|
|
38
|
-
Publish to PyPI
|
|
39
|
-
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'wineslab/dApp-library'
|
|
40
|
-
needs:
|
|
41
|
-
- build
|
|
42
|
-
runs-on: ubuntu-latest
|
|
43
|
-
environment:
|
|
44
|
-
name: pypi
|
|
45
|
-
url: https://pypi.org/p/dapps
|
|
46
|
-
permissions:
|
|
47
|
-
id-token: write
|
|
48
|
-
|
|
49
|
-
steps:
|
|
50
|
-
- name: Download all the dists
|
|
51
|
-
uses: actions/download-artifact@v4
|
|
52
|
-
with:
|
|
53
|
-
name: python-package-distributions
|
|
54
|
-
path: dist/
|
|
55
|
-
- name: Publish distribution 📦 to PyPI
|
|
56
|
-
uses: pypa/gh-action-pypi-publish@release/v1
|
|
57
|
-
|
|
58
|
-
github-release:
|
|
59
|
-
name: >-
|
|
60
|
-
Sign packages with Sigstore and upload them to GitHub Release
|
|
61
|
-
needs:
|
|
62
|
-
- publish-to-pypi
|
|
63
|
-
runs-on: ubuntu-latest
|
|
64
|
-
if: github.repository == 'wineslab/dApp-library'
|
|
65
|
-
|
|
66
|
-
permissions:
|
|
67
|
-
contents: write
|
|
68
|
-
id-token: write
|
|
69
|
-
|
|
70
|
-
steps:
|
|
71
|
-
- name: Download all the dists
|
|
72
|
-
uses: actions/download-artifact@v4
|
|
73
|
-
with:
|
|
74
|
-
name: python-package-distributions
|
|
75
|
-
path: dist/
|
|
76
|
-
- name: Sign the dists with Sigstore
|
|
77
|
-
uses: sigstore/gh-action-sigstore-python@v3.0.0
|
|
78
|
-
with:
|
|
79
|
-
inputs: >-
|
|
80
|
-
./dist/*.tar.gz
|
|
81
|
-
./dist/*.whl
|
|
82
|
-
- name: Create GitHub Release
|
|
83
|
-
env:
|
|
84
|
-
GITHUB_TOKEN: ${{ github.token }}
|
|
85
|
-
run: >-
|
|
86
|
-
gh release create
|
|
87
|
-
"$GITHUB_REF_NAME"
|
|
88
|
-
--repo "$GITHUB_REPOSITORY"
|
|
89
|
-
--notes ""
|
|
90
|
-
- name: Upload artifact signatures to GitHub Release
|
|
91
|
-
env:
|
|
92
|
-
GITHUB_TOKEN: ${{ github.token }}
|
|
93
|
-
run: >-
|
|
94
|
-
gh release upload
|
|
95
|
-
"$GITHUB_REF_NAME" dist/**
|
|
96
|
-
--repo "$GITHUB_REPOSITORY"
|
|
97
|
-
|
|
98
|
-
publish-to-testpypi:
|
|
99
|
-
name: Publish to TestPyPI
|
|
100
|
-
needs:
|
|
101
|
-
- build
|
|
102
|
-
runs-on: ubuntu-latest
|
|
103
|
-
if: github.repository == 'wineslab/dApp-library'
|
|
104
|
-
|
|
105
|
-
environment:
|
|
106
|
-
name: testpypi
|
|
107
|
-
url: https://test.pypi.org/p/dapps
|
|
108
|
-
|
|
109
|
-
permissions:
|
|
110
|
-
id-token: write
|
|
111
|
-
|
|
112
|
-
steps:
|
|
113
|
-
- name: Download all the dists
|
|
114
|
-
uses: actions/download-artifact@v4
|
|
115
|
-
with:
|
|
116
|
-
name: python-package-distributions
|
|
117
|
-
path: dist/
|
|
118
|
-
- name: Publish distribution 📦 to TestPyPI
|
|
119
|
-
uses: pypa/gh-action-pypi-publish@release/v1
|
|
120
|
-
with:
|
|
121
|
-
repository-url: https://test.pypi.org/legacy/
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
name: Tag on VERSION change
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
paths:
|
|
8
|
-
- 'VERSION' # Only trigger if VERSION file changes
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
create-tag:
|
|
12
|
-
runs-on: ubuntu-latest
|
|
13
|
-
steps:
|
|
14
|
-
- name: Checkout repository
|
|
15
|
-
uses: actions/checkout@v4
|
|
16
|
-
with:
|
|
17
|
-
fetch-depth: 0 # Ensure we fetch all tags
|
|
18
|
-
|
|
19
|
-
- name: Read VERSION file
|
|
20
|
-
id: get_version
|
|
21
|
-
run: echo "VERSION=$(cat VERSION | tr -d '[:space:]')" >> $GITHUB_ENV
|
|
22
|
-
|
|
23
|
-
- name: Check if tag exists
|
|
24
|
-
id: check_tag
|
|
25
|
-
run: |
|
|
26
|
-
if git rev-parse "refs/tags/$VERSION" >/dev/null 2>&1; then
|
|
27
|
-
echo "Tag $VERSION already exists. Skipping..."
|
|
28
|
-
echo "EXISTS=true" >> $GITHUB_ENV
|
|
29
|
-
else
|
|
30
|
-
echo "EXISTS=false" >> $GITHUB_ENV
|
|
31
|
-
fi
|
|
32
|
-
|
|
33
|
-
- name: Create and push tag
|
|
34
|
-
if: env.EXISTS == 'false'
|
|
35
|
-
run: |
|
|
36
|
-
git tag $VERSION
|
|
37
|
-
git push origin $VERSION
|
|
38
|
-
env:
|
|
39
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
40
|
-
|
|
41
|
-
- name: Trigger Release Workflow
|
|
42
|
-
if: github.repository == 'wineslab/dApp-library' && env.EXISTS == 'false'
|
|
43
|
-
run: |
|
|
44
|
-
curl -X POST -H "Accept: application/vnd.github.v3+json" \
|
|
45
|
-
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
|
|
46
|
-
https://api.github.com/repos/${{ github.repository }}/actions/workflows/release.yml/dispatches \
|
|
47
|
-
-d '{"ref": "main"}'
|
|
48
|
-
env:
|
|
49
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
dapps-0.0.1/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.0.1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|