enode-host 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,136 @@
1
+ import socket
2
+ import time
3
+ import threading
4
+ import logging
5
+ import struct
6
+ import datetime
7
+ import getmac
8
+ import os
9
+ from queue import Queue
10
+ import config
11
+ from scipy.interpolate import interp1d
12
+ from numpy import where, logical_and, empty, append, array, delete, floor
13
+ try:
14
+ from . import queues
15
+ except ImportError:
16
+ import queues
17
+
18
+
19
+ # CONFIGURATION
20
+ rawFileLength_sec = config.rawFileLength_sec
21
+ port = config.port
22
+ target_dir = config.target_dir
23
+ from model import packet_size, ChannelType, CmdType
24
+
25
+ npackets = 63
26
+
27
+ logger = logging.getLogger(__name__)
28
+
29
+ class Esp_Mesh():
30
+
31
+ def __init__(self, model):
32
+
33
+ self.model = model
34
+ self.sockets = {}
35
+
36
+ thread = threading.Thread(target = self.mesh_svr_begin)
37
+ thread.start()
38
+ logger.info("mesh_server started.")
39
+
40
+ def get_ip_address(self):
41
+
42
+ try:
43
+ # This will get the local IP address of your machine
44
+ host_name = socket.gethostname()
45
+ ip_address = socket.gethostbyname(host_name)
46
+ return ip_address
47
+ except socket.error as e:
48
+ print(f"Error: {e}")
49
+ return None
50
+
51
+ def handle_client(self, client_socket, ip_address):
52
+
53
+ logger.info("handle_client called...")
54
+ data = bytearray()
55
+ nodeID = 0
56
+ # client_socket.settimeout(0)
57
+ is_socket_stored = False
58
+
59
+ while True:
60
+ try:
61
+ # Managing Sockets: store the handle for access from outside
62
+ if True:
63
+ data += client_socket.recv(packet_size * npackets)
64
+ else:
65
+ data += client_socket.recv(packet_size * 1)
66
+ # Storing socket handler for access from outside
67
+ if not is_socket_stored and len(data) >= packet_size:
68
+ packet = data[:packet_size]
69
+ rec = struct.unpack('>H', packet[:2]) # B = unsigned char (1byte),
70
+ # H = unsigned short integer (2byte),
71
+ nodeID = rec[0] # consisting of nodeType (uint8_t) + nodeNUmber (uint8_t)
72
+ logger.info('nodeID={}'.format(nodeID))
73
+ self.sockets[nodeID] = client_socket
74
+ is_socket_stored = True
75
+ # forward the data to parser
76
+ if is_socket_stored:
77
+ self.model.data_push(nodeID, data)
78
+ logger.debug('data_pushed {} bytes'.format(len(data)))
79
+ data.clear()
80
+ #time.sleep(0.5)
81
+
82
+ # except BlockingIOError:
83
+ # time.sleep(0.1)
84
+ # except socket.timeout:
85
+ # time.sleep(0.1)
86
+ except Exception as e:
87
+ errnum = e.args[0]
88
+ if errnum in [104, 113, 110] :
89
+ # 110: connection tiemout
90
+ # peer closed the connection, then svr closes it as well
91
+ break
92
+ else:
93
+ raise
94
+ # delete socket handle if disconnected
95
+ del self.sockets[nodeID]
96
+ logger.info("close()...")
97
+ client_socket.close()
98
+ # queues.Mesh2GUI.put({'updateType': 1, 'nodeID': nodeID, 'connection': False})
99
+
100
+ def mesh_svr_begin(self):
101
+
102
+ # Create a socket object
103
+ server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
104
+ # print("recv buffer size = {}".format(server_socket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)))
105
+ hostname = socket.gethostname()
106
+ # if hostname in ['wing1a', 'wing3.lan']:
107
+ # host = self.get_ip_address()
108
+ # else:
109
+ # host = '192.168.1.104'
110
+ host = '192.168.1.202'
111
+ logger.info(f"ip address= {host}")
112
+
113
+ while(True):
114
+ try:
115
+ server_socket.bind((host, port)) # Bind the socket to the host and port
116
+ break
117
+ except:
118
+ print(".")
119
+ time.sleep(1)
120
+ server_socket.listen(20) # Listen for incoming connections; The argument is the maximum number of queued connections
121
+ logger.info(f"Server is listening on {host}:{port}")
122
+ while True:
123
+ logger.info("Waiting for a connection...")
124
+ client_socket, client_address = server_socket.accept()
125
+ logger.info(f"Accepted connection from {client_address}")
126
+ # Start a new thread to handle the client
127
+ client_handler = threading.Thread(target=self.handle_client, args=(client_socket, client_address,))
128
+ client_handler.start()
129
+
130
+ def send_cmd(self, nodeID, cmd, data0 = 0, data1 = 0):
131
+
132
+ msg = struct.pack('=BBBBB', cmd, data0, data1, 0, 0)
133
+ logger.info('msg={}'.format(msg))
134
+ self.sockets[nodeID].send(msg)
135
+
136
+
@@ -0,0 +1,113 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Form implementation generated from reading ui file 'gui_v2.ui'
4
+ #
5
+ # Created by: PyQt5 UI code generator 5.15.9
6
+ #
7
+ # WARNING: Any manual changes made to this file will be lost when pyuic5 is
8
+ # run again. Do not edit this file unless you know what you are doing.
9
+
10
+
11
+ from PyQt5 import QtCore, QtGui, QtWidgets
12
+
13
+
14
+ class Ui_MainWindow(object):
15
+ def setupUi(self, MainWindow):
16
+ MainWindow.setObjectName("MainWindow")
17
+ MainWindow.resize(860, 596)
18
+ self.centralwidget = QtWidgets.QWidget(MainWindow)
19
+ self.centralwidget.setObjectName("centralwidget")
20
+ self.widget = QtWidgets.QWidget(self.centralwidget)
21
+ # self.widget.setGeometry(QtCore.QRect(10, 10, 831, 531))
22
+ self.widget.setObjectName("widget")
23
+
24
+ #
25
+ # LAYOUTS
26
+ #
27
+
28
+ # Vertical layout
29
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
30
+ # self.verticalLayout.setContentsMargins(0, 0, 0, 0)
31
+ self.verticalLayout.setObjectName("verticalLayout")
32
+
33
+ # Horizontal layout 1
34
+ self.horizontalLayout1 = QtWidgets.QHBoxLayout()
35
+ self.horizontalLayout1.setObjectName("horizontalLayout1")
36
+
37
+ # Horizontal layout 2
38
+ self.horizontalLayout2 = QtWidgets.QHBoxLayout()
39
+ self.horizontalLayout2.setObjectName("horizontalLayout2")
40
+
41
+ self.verticalLayout.addLayout(self.horizontalLayout1)
42
+ self.verticalLayout.addLayout(self.horizontalLayout2)
43
+
44
+ # add Widgets for Horizontal layout1
45
+ self.label = QtWidgets.QLabel(self.widget)
46
+ font = QtGui.QFont()
47
+ font.setFamily("Arial")
48
+ font.setBold(True)
49
+ font.setWeight(75)
50
+ self.label.setFont(font)
51
+ self.label.setObjectName("label")
52
+ self.label.setText("Number of Nodes")
53
+ self.horizontalLayout1.addWidget(self.label)
54
+
55
+ self.spinBox = QtWidgets.QSpinBox(self.widget)
56
+ self.spinBox.setMaximum(16)
57
+ self.spinBox.setProperty("value", 14)
58
+ self.spinBox.setObjectName("spinBox")
59
+ self.spinBox.valueChanged.connect(self.update_nnodes)
60
+ self.horizontalLayout1.addWidget(self.spinBox)
61
+
62
+ self.pushButton = QtWidgets.QPushButton(self.widget)
63
+ self.pushButton.setObjectName("pushButton")
64
+ self.horizontalLayout1.addWidget(self.pushButton)
65
+ self.pushButton_2 = QtWidgets.QPushButton(self.widget)
66
+ self.pushButton_2.setObjectName("pushButton_2")
67
+ self.horizontalLayout1.addWidget(self.pushButton_2)
68
+
69
+ # Add widgets for Horizontal layout2
70
+ self.tableView = QtWidgets.QTableView(self.widget)
71
+ self.tableView.setObjectName("tableView")
72
+ self.horizontalLayout2.addWidget(self.tableView, stretch = 1)
73
+
74
+ self.listView = []
75
+ # self.listView = QtWidgets.QListView(self.widget)
76
+ # self.listView.setObjectName("listView")
77
+ # self.verticalLayout.addWidget(self.listView, stretch=3)
78
+
79
+ self.centralwidget.setLayout(self.verticalLayout)
80
+ MainWindow.setCentralWidget(self.centralwidget)
81
+
82
+ # self.menubar = QtWidgets.QMenuBar(MainWindow)
83
+ # self.menubar.setGeometry(QtCore.QRect(0, 0, 860, 20))
84
+ # self.menubar.setObjectName("menubar")
85
+ # self.menu_File = QtWidgets.QMenu(self.menubar)
86
+ # self.menu_File.setObjectName("menu_File")
87
+ # MainWindow.setMenuBar(self.menubar)
88
+ # self.statusbar = QtWidgets.QStatusBar(MainWindow)
89
+ # self.statusbar.setObjectName("statusbar")
90
+ # MainWindow.setStatusBar(self.statusbar)
91
+ # self.action_Open = QtWidgets.QAction(MainWindow)
92
+ # self.action_Open.setObjectName("action_Open")
93
+ # self.action_Action1 = QtWidgets.QAction(MainWindow)
94
+ # self.action_Action1.setObjectName("action_Action1")
95
+ # self.menu_File.addAction(self.action_Open)
96
+ # self.menubar.addAction(self.menu_File.menuAction())
97
+
98
+ self.retranslateUi(MainWindow)
99
+ QtCore.QMetaObject.connectSlotsByName(MainWindow)
100
+
101
+ def retranslateUi(self, MainWindow):
102
+ pass
103
+ _translate = QtCore.QCoreApplication.translate
104
+ MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
105
+ self.label.setText(_translate("MainWindow", "Number of Nodes"))
106
+ self.pushButton.setText(_translate("MainWindow", "Start DAQ All"))
107
+ self.pushButton_2.setText(_translate("MainWindow", "Reboot All"))
108
+ # self.menu_File.setTitle(_translate("MainWindow", "&File"))
109
+ # self.action_Open.setText(_translate("MainWindow", "&Quit"))
110
+ # self.action_Action1.setText(_translate("MainWindow", "&Action1"))
111
+
112
+ def update_nnodes(self, value):
113
+ print("nnode={}".format(value))
@@ -0,0 +1,270 @@
1
+ #!/usr/local/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ ###########################################################################
5
+ ## Python code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
6
+ ## http://www.wxformbuilder.org/
7
+ ##
8
+ ## PLEASE DO *NOT* EDIT THIS FILE!
9
+ ###########################################################################
10
+
11
+ import wx
12
+ import wx.xrc
13
+ import wx.grid
14
+
15
+ import gettext
16
+ _ = gettext.gettext
17
+
18
+ ###########################################################################
19
+ ## Class MyFrame1
20
+ ###########################################################################
21
+
22
+ class MyFrame1 ( wx.Frame ):
23
+
24
+ def __init__( self, parent ):
25
+ wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = _(u"Wireless Sensor DAQ"), pos = wx.DefaultPosition, size = wx.Size( 1024,600 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
26
+
27
+ self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
28
+
29
+ bSizer1 = wx.BoxSizer( wx.VERTICAL )
30
+
31
+ bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
32
+
33
+ self.m_staticText2 = wx.StaticText( self, wx.ID_ANY, _(u"Sensor Nodes:"), wx.DefaultPosition, wx.DefaultSize, 0 )
34
+ self.m_staticText2.Wrap( -1 )
35
+
36
+ bSizer2.Add( self.m_staticText2, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
37
+
38
+ self.m_textCtrl2 = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
39
+ bSizer2.Add( self.m_textCtrl2, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
40
+
41
+ self.m_staticText3 = wx.StaticText( self, wx.ID_ANY, _(u"Fs="), wx.DefaultPosition, wx.DefaultSize, 0 )
42
+ self.m_staticText3.Wrap( -1 )
43
+
44
+ bSizer2.Add( self.m_staticText3, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
45
+
46
+ m_choice1Choices = [ _(u"62.5"), _(u"125") ]
47
+ self.m_choice1 = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice1Choices, 0 )
48
+ self.m_choice1.SetSelection( 0 )
49
+ bSizer2.Add( self.m_choice1, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
50
+
51
+ self.m_staticText4 = wx.StaticText( self, wx.ID_ANY, _(u"Hz"), wx.DefaultPosition, wx.DefaultSize, 0 )
52
+ self.m_staticText4.Wrap( -1 )
53
+
54
+ bSizer2.Add( self.m_staticText4, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
55
+
56
+ self.m_button1 = wx.Button( self, wx.ID_ANY, _(u"Start DAQ"), wx.DefaultPosition, wx.DefaultSize, 0 )
57
+ bSizer2.Add( self.m_button1, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
58
+
59
+ self.m_button2 = wx.Button( self, wx.ID_ANY, _(u"Stop DAQ"), wx.DefaultPosition, wx.DefaultSize, 0 )
60
+ bSizer2.Add( self.m_button2, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
61
+
62
+
63
+ bSizer1.Add( bSizer2, 0, wx.EXPAND, 5 )
64
+
65
+ bSizer3 = wx.BoxSizer( wx.HORIZONTAL )
66
+
67
+ bSizer4 = wx.BoxSizer( wx.VERTICAL )
68
+
69
+ self.m_staticText21 = wx.StaticText( self, wx.ID_ANY, _(u"WiFi Mesh Status"), wx.DefaultPosition, wx.DefaultSize, 0 )
70
+ self.m_staticText21.Wrap( -1 )
71
+
72
+ bSizer4.Add( self.m_staticText21, 0, wx.ALL, 5 )
73
+
74
+ self.m_grid2 = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
75
+
76
+ # Grid
77
+ self.m_grid2.CreateGrid( 5, 6 )
78
+ self.m_grid2.EnableEditing( True )
79
+ self.m_grid2.EnableGridLines( True )
80
+ self.m_grid2.EnableDragGridSize( True )
81
+ self.m_grid2.SetMargins( 0, 0 )
82
+
83
+ # Columns
84
+ self.m_grid2.SetColSize( 0, 70 )
85
+ self.m_grid2.SetColSize( 1, 100 )
86
+ self.m_grid2.SetColSize( 2, 20 )
87
+ self.m_grid2.SetColSize( 3, 40 )
88
+ self.m_grid2.SetColSize( 4, 40 )
89
+ self.m_grid2.SetColSize( 5, 45 )
90
+ self.m_grid2.EnableDragColMove( False )
91
+ self.m_grid2.EnableDragColSize( True )
92
+ self.m_grid2.SetColLabelValue( 0, _(u"Node ID") )
93
+ self.m_grid2.SetColLabelValue( 1, _(u"Status") )
94
+ self.m_grid2.SetColLabelValue( 2, _(u"L") )
95
+ self.m_grid2.SetColLabelValue( 3, _(u"RSSI") )
96
+ self.m_grid2.SetColLabelValue( 4, _(u"PPS") )
97
+ self.m_grid2.SetColLabelValue( 5, _(u"Data") )
98
+ self.m_grid2.SetColLabelSize( wx.grid.GRID_AUTOSIZE )
99
+ self.m_grid2.SetColLabelAlignment( wx.ALIGN_CENTER, wx.ALIGN_CENTER )
100
+
101
+ # Rows
102
+ self.m_grid2.EnableDragRowSize( True )
103
+ self.m_grid2.SetRowLabelSize( wx.grid.GRID_AUTOSIZE )
104
+ self.m_grid2.SetRowLabelAlignment( wx.ALIGN_CENTER, wx.ALIGN_CENTER )
105
+
106
+ # Label Appearance
107
+
108
+ # Cell Defaults
109
+ self.m_grid2.SetDefaultCellAlignment( wx.ALIGN_LEFT, wx.ALIGN_TOP )
110
+ bSizer4.Add( self.m_grid2, 1, wx.ALL|wx.EXPAND, 5 )
111
+
112
+
113
+ bSizer3.Add( bSizer4, 0, wx.EXPAND, 5 )
114
+
115
+ self.m_notebook2 = wx.Notebook( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
116
+ self.m_panel1 = wx.Panel( self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
117
+ self.m_notebook2.AddPage( self.m_panel1, _(u"Time history plot"), True )
118
+ self.m_panel2 = wx.Panel( self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
119
+ self.m_notebook2.AddPage( self.m_panel2, _(u"PSD plot"), False )
120
+
121
+ bSizer3.Add( self.m_notebook2, 1, wx.ALL|wx.EXPAND, 5 )
122
+
123
+
124
+ bSizer1.Add( bSizer3, 1, wx.EXPAND, 5 )
125
+
126
+ self.m_textCtrl21 = wx.TextCtrl( self, wx.ID_ANY, _(u"\"test line 1\ntest2 line|\""), wx.DefaultPosition, wx.Size( -1,100 ), 0 )
127
+ bSizer1.Add( self.m_textCtrl21, 0, wx.ALL|wx.EXPAND, 5 )
128
+
129
+
130
+ self.SetSizer( bSizer1 )
131
+ self.Layout()
132
+
133
+
134
+ # MENU
135
+ self.m_statusBar1 = self.CreateStatusBar(1, wx.STB_SIZEGRIP, wx.ID_ANY)
136
+ self.m_menubar = wx.MenuBar(0)
137
+ self.m_menu_file = wx.Menu()
138
+ self.m_menu_file_open = wx.MenuItem(self.m_menu_file, wx.ID_ANY, _(u"&Open"), wx.EmptyString, wx.ITEM_NORMAL)
139
+ self.m_menu_file_save = wx.MenuItem(self.m_menu_file, wx.ID_ANY, _(u"&Save"), wx.EmptyString, wx.ITEM_NORMAL)
140
+ self.m_menu_file_quit = wx.MenuItem(self.m_menu_file, wx.ID_ANY, _(u"&Quit"), wx.EmptyString, wx.ITEM_NORMAL)
141
+ self.m_menu_file.Append(self.m_menu_file_open)
142
+ self.m_menu_file.Append(self.m_menu_file_save)
143
+ self.m_menu_file.AppendSeparator()
144
+ self.m_menu_file.Append(self.m_menu_file_quit)
145
+ self.m_menubar.Append(self.m_menu_file, _(u"&File"))
146
+
147
+ self.m_menu_help = wx.Menu()
148
+ self.m_menu_help_about = wx.MenuItem(self.m_menu_help, wx.ID_ANY, _(u"&Help"), wx.EmptyString, wx.ITEM_NORMAL)
149
+ self.m_menu_help.Append(self.m_menu_help_about)
150
+ self.m_menubar.Append(self.m_menu_help, _(u"&Help"))
151
+
152
+ self.SetMenuBar(self.m_menubar)
153
+
154
+ self.Centre( wx.BOTH )
155
+
156
+ # Connect Events
157
+ self.m_textCtrl2.Bind( wx.EVT_TEXT, self.test )
158
+
159
+
160
+
161
+ def __del__( self ):
162
+ pass
163
+
164
+
165
+ # Virtual event handlers, override them in your derived class
166
+ def test( self, event ):
167
+ event.Skip()
168
+
169
+ import wx
170
+ import wx.lib.agw.aui as aui
171
+ import wx.lib.mixins.inspection as wit
172
+ from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
173
+ from matplotlib.backends.backend_wxagg import \
174
+ NavigationToolbar2WxAgg as NavigationToolbar
175
+ from matplotlib.figure import Figure
176
+
177
+ class Plot(wx.Panel):
178
+ def __init__(self, parent, id=-1, dpi=None, **kwargs):
179
+ super().__init__(parent, id=id, **kwargs)
180
+ self.figure = Figure(dpi=dpi, figsize=(2, 2))
181
+ self.canvas = FigureCanvas(self, -1, self.figure)
182
+ self.toolbar = NavigationToolbar(self.canvas)
183
+ self.toolbar.Realize()
184
+
185
+ sizer = wx.BoxSizer(wx.VERTICAL)
186
+ sizer.Add(self.canvas, 1, wx.EXPAND)
187
+ sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
188
+ self.SetSizer(sizer)
189
+
190
+ class PlotNotebook(wx.Panel):
191
+ def __init__(self, parent, id=-1):
192
+ super().__init__(parent, id=id)
193
+ self.nb = aui.AuiNotebook(self)
194
+ sizer = wx.BoxSizer()
195
+ sizer.Add(self.nb, 1, wx.EXPAND)
196
+ self.SetSizer(sizer)
197
+
198
+ def add(self, name="plot"):
199
+ page = Plot(self.nb)
200
+ self.nb.AddPage(page, name)
201
+ return page.figure
202
+
203
+
204
+ import wx.grid as gridlib
205
+ import configparser
206
+ import os
207
+
208
+ CONFIG_FILE = 'config.ini'
209
+
210
+ def save_config(options):
211
+ config = configparser.ConfigParser()
212
+
213
+ config['Settings'] = {
214
+ 'option1': options['option1'],
215
+ 'option2': options['option2']
216
+ }
217
+
218
+ with open(CONFIG_FILE, 'w') as configfile:
219
+ config.write(configfile)
220
+
221
+ def load_config():
222
+ config = configparser.ConfigParser()
223
+
224
+ if not os.path.exists(CONFIG_FILE):
225
+ # Return default options if config file doesn't exist
226
+ return {
227
+ 'option1': 'default_value1',
228
+ 'option2': 'default_value2'
229
+ }
230
+
231
+ config.read(CONFIG_FILE)
232
+ options = {
233
+ 'option1': config.get('Settings', 'option1', fallback='default_value1'),
234
+ 'option2': config.get('Settings', 'option2', fallback='default_value2')
235
+ }
236
+
237
+ return options
238
+
239
+ def MainWindow():
240
+ # window = wx.Frame(None, title = "wxPython Frame", size = (300,200))
241
+ frame1 = MyFrame1(None)
242
+
243
+
244
+ fig1 = Plot(frame1.m_panel1)
245
+ # plotter = PlotNotebook(frame1.m_notebook2)
246
+ axes1 = fig1.figure.add_subplot()
247
+ axes1.plot([1, 2, 3], [2, 1, 4])
248
+ fig2 = Plot(frame1.m_panel2)
249
+ axes2 = fig2.figure.add_subplot()
250
+ axes2.plot([1, 2, 3, 4, 5], [2, 1, 4, 2, 3])
251
+
252
+ canvas = FigureCanvas(frame1.m_panel1, -1, fig1.figure)
253
+ sizer = wx.BoxSizer(wx.VERTICAL)
254
+ sizer.Add(canvas, 1, wx.EXPAND)
255
+
256
+ # Set the sizer for the panel
257
+ frame1.m_panel1.SetSizer(sizer)
258
+
259
+ # Change the background color of cell (1, 1)
260
+ attr = gridlib.GridCellAttr()
261
+ attr.SetBackgroundColour(wx.Colour(255, 255, 0)) # Yellow
262
+ frame1.m_grid2.SetAttr(1, 1, attr)
263
+
264
+
265
+ frame1.Show(True)
266
+
267
+
268
+
269
+ return frame1
270
+
@@ -0,0 +1,27 @@
1
+ from numpy import *
2
+ import struct
3
+ import datetime
4
+ import os
5
+ import pandas as pd
6
+
7
+
8
+ def load_adxl355_file(filename):
9
+ t, y = [], []
10
+ with open(filename, 'rb') as file:
11
+ while True:
12
+ chunk = file.read(24)
13
+ if not chunk:
14
+ break
15
+ data = struct.unpack('<QIfff', chunk)
16
+
17
+ t_ = datetime.datetime.fromtimestamp(data[0])
18
+ t_ = t_.replace(microsecond = data[1])
19
+ t.append(t_)
20
+ y.append(data[2:])
21
+ t = array(t)
22
+ y = array(y)
23
+ df = pd.DataFrame({'timestamps': t, "X": y[:, 0], "Y": y[:, 1], "Z": y[:, 2]})
24
+ df.set_index(df['timestamps'], inplace = True)
25
+ del df['timestamps']
26
+ return df
27
+
File without changes
File without changes
enode_host/backup/s.py ADDED
@@ -0,0 +1,151 @@
1
+ #!/usr/local/bin/python3
2
+
3
+ #----------------------------------------------
4
+ # HOW TO USE THE SYSTEM
5
+ #
6
+ # 1. please execute this file first, so that the server is ready to receive data from ndoes
7
+ # 2. turn on the node(s)
8
+ # - the PPS LED on the display can be believed
9
+ # - please don't believe RSSI, Lv, BAT %, as they are not completed yet.
10
+ # 3. Files are saved under data2 folder in HDF
11
+ # 4. Please read example.ipynb for how to load data file and display it
12
+ # - Please notice the time is in UTC to avoid any issues regarding British Summer Time
13
+ # 5. For time-sync, never reset the acc node, but power-cycle it.
14
+ # - there are two buttons on the sensor node:
15
+ # - one for power next to the USB-c port
16
+ # - the other for reset next to the SD slot
17
+ # - pressing the pwr button for 5 sec will shutdown the node, and pressing it for 1 sec will start the node
18
+
19
+
20
+ import logging
21
+ import gui
22
+ import mesh
23
+ import sys
24
+ from PyQt5 import QtCore, QtGui, QtWidgets
25
+ from PyQt5.QtGui import QColor
26
+ import threading
27
+ import queues
28
+ from numpy import array
29
+ import shm_sigproc
30
+ import glob
31
+ import os
32
+
33
+ from matplotlib.pyplot import *
34
+
35
+
36
+
37
+ os.makedirs("log", exist_ok = True)
38
+ os.makedirs("data", exist_ok = True)
39
+ os.makedirs("data2", exist_ok = True)
40
+
41
+
42
+ logging.basicConfig(level=logging.INFO, # Set the minimum log level
43
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
44
+ handlers=[logging.FileHandler('log/my_log_file.log'), logging.StreamHandler()])
45
+ logger = logging.getLogger(__name__)
46
+
47
+
48
+ df = []
49
+ psd = []
50
+
51
+
52
+ def begin():
53
+
54
+ mesh.begin()
55
+ shm_sigproc.begin()
56
+
57
+ app = QtWidgets.QApplication(sys.argv)
58
+ window = gui.MainWindow()
59
+ app.exec_()
60
+
61
+
62
+
63
+ def export():
64
+
65
+ global df
66
+
67
+ raw_data_dir = 'data2'
68
+
69
+ node_IDs = []
70
+
71
+ import os
72
+ import pandas as pd
73
+
74
+
75
+ entries = os.listdir(raw_data_dir)
76
+ files = [f for f in entries if f.endswith('.hd5')]
77
+
78
+ # IDENTIFY NODE IDs
79
+ for file in files:
80
+ node_IDs.append(file.split('-')[0])
81
+ node_IDs = sorted(set(node_IDs))
82
+
83
+ # READ AND MERGE ALL RAW DATA FILES
84
+ dfs = []
85
+ for node_ID in node_IDs:
86
+ dfs_ = []
87
+ files_ = [f for f in entries if f.endswith('.hd5') and f.startswith(node_ID)]
88
+ for file_ in files_:
89
+ dfs_.append(pd.read_hdf(os.path.join(raw_data_dir, file_)))
90
+ df_ = pd.concat(dfs_, axis = 0)
91
+ df_ = df_.rename(columns={
92
+ 'X': '{}-X'.format(node_ID),
93
+ 'Y': '{}-Y'.format(node_ID),
94
+ 'Z': '{}-Z'.format(node_ID)
95
+ })
96
+ dfs.append(df_)
97
+
98
+ df = pd.concat(dfs, axis = 1)
99
+ df = df.dropna()
100
+ df.plot(figsize=(24, 6))
101
+ show()
102
+
103
+ filename = "data/daq-{}".format(df.index[0].strftime("%Y_%m%d_%H%M"))
104
+ df.to_hdf(filename, key="df")
105
+
106
+
107
+
108
+ def clear():
109
+ # DELETE TEMPORARIL FILES
110
+ for file in glob.glob("data2/*.hd5"):
111
+ try:
112
+ os.remove(file)
113
+ except Exception as e:
114
+ logger.error(f"Error deleting file {file}: {e}")
115
+
116
+
117
+
118
+ if __name__ == '__main__':
119
+ begin()
120
+
121
+ # thread = threading.Thread(target = main)
122
+ # thread.start()
123
+ # logger.info("mesh_server started.")
124
+
125
+ # grid_time = int(datetime.datetime.now().timestamp()/config.TIME_WINDOW_LENGTH_SEC) * config.TIME_WINDOW_LENGTH_SEC
126
+
127
+ # timeWindow = [datetime.datetime.fromtimestamp(grid_time),
128
+ # datetime.datetime.fromtimestamp(grid_time + config.TIME_WINDOW_LENGTH_SEC)]
129
+ # tdata = thp_lines[nodeID-1].get_xdata()
130
+ # ydata = thp_lines[nodeID-1].get_ydata()
131
+ # idx = where(array(tdata) < timeWindow[0])
132
+ # tdata = delete(tdata, idx[0])
133
+ # ydata = delete(ydata, idx[0], 0)
134
+ # tdata = append(tdata, t)
135
+ # ydata = append(ydata, y)
136
+ # thp_lines[nodeID - 1].set_xdata(tdata)
137
+ # thp_lines[nodeID - 1].set_ydata(ydata)
138
+ # sc = window.m_ui.listView
139
+ # sc.axes[0].set_xlim(timeWindow[0], timeWindow[1])
140
+ # sc.axes[0].xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))
141
+ # draw()
142
+ # # pause(0.05)
143
+ # # show(block = False)
144
+ # logger.info("len(tdata) = {}".format(len(tdata)))
145
+
146
+
147
+ # for t, y_ in zip(t, y):
148
+ # logger.info("{}, {}, {}, {}".format(t, y_[0], y_[1], y_[2]))
149
+
150
+ # time.sleep(0.1)
151
+