first time questioner here! I´m currently working on a python project that´s supposed to read soil moisture through a sensor on a raspberry pi, which then sends the data to another laptop through a socket connection. That other laptop displays the data in a UI. That UI is also capable of controllig the script flow. My Server starts up just fine, but when the client connects to it(connection itself works), I get the following Error Stack:
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
self.run()
File "/usr/lib/python3.5/threading.py", line 862, in run
self._target(self._args, **self._kwargs)
File "/home/pi/Py_Scripts/MoistureSensor/Server.py", line 77, in worker_recv
self.JSON_Control = pickle.loads(self.data_recv)
EOFError: Ran out of input
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
self.run()
File "/usr/lib/python3.5/threading.py", line 862, in run
self._target(self._args, **self._kwargs)
File "/home/pi/Py_Scripts/MoistureSensor/Server.py", line 70, in worker_send
self.conn.send(self.data_send)
BrokenPipeError: [Errno 32] Broken pipe
My Scripts look as follows:
Client-side:
import sys
from socket import *
from threading import Thread
from time import sleep
import pickle
from PySide6 import QtWidgets, QtGui
class MyClient:
def __init__(self, server_port, buf_size, host):
self.server_port = server_port
self.buf_size = buf_size
self.host = host
self.data_send = None
self.data_recv = None
self.exit = False
self.JSON_Control = {
"measure": False,
"exit": False,
}
self.JSON_Moisture = {
"moisture_level": 0
}
self.socket_connection = socket(AF_INET, SOCK_STREAM)
self.socket_connection.connect((self.host, self.server_port))
print("Connected with Server: %s: " % self.host)
# thread for sending
self.thread_send = Thread(target=self.worker_send)
# thread for receiving
self.thread_recv = Thread(target=self.worker_recv)
# starting Threads
self.thread_send.start()
self.thread_recv.start()
def worker_send(self):
while not self.exit:
self.data_send = pickle.dumps(self.JSON_Control)
self.socket_connection.send(self.data_send)
sleep(0.5)
def worker_recv(self):
while not self.exit:
self.data_recv = self.socket_connection.recv(self.buf_size)
if self.data_recv is not None:
self.JSON_Moisture = pickle.loads(self.data_recv)
class UiDisplay(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.moisture_label = None
self.moisture_level = None
self.start_button = None
self.refresh_button = None
self.stop_button = None
self.reset_button = None
self.quit_button = None
self.create_widgets()
def create_widgets(self):
# create a label to display the current time
self.moisture_label = QtWidgets.QLabel(self)
self.moisture_label.setFont(QtGui.QFont("Helvetica", 16))
self.moisture_level = client.JSON_Moisture["moisture_level"]
self.moisture_label.setText('Bodenfeuchtigkeit: ' + str(self.moisture_level)[:3] + '%')
# button to start the weight measuring
self.start_button = QtWidgets.QPushButton("Start measuring", self)
self.start_button.clicked.connect(self.measure_moisture)
# button to refresh the Weight label
self.refresh_button = QtWidgets.QPushButton("Refresh", self)
self.refresh_button.clicked.connect(self.refresh)
# button to stop measuring
self.stop_button = QtWidgets.QPushButton("Stop measuring", self)
self.stop_button.clicked.connect(self.stop_measuring)
# button to quit the program
self.quit_button = QtWidgets.QPushButton("Quit", self)
self.quit_button.clicked.connect(self.quit)
# create a layout to hold the widgets
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.moisture_label)
layout.addWidget(self.start_button)
layout.addWidget(self.refresh_button)
layout.addWidget(self.stop_button)
layout.addWidget(self.reset_button)
layout.addWidget(self.quit_button)
self.setLayout(layout)
def measure_moisture(self):
client.JSON_Control["measure"] = True
def refresh(self):
# get current weight ( niederlag auf ein qm rechnen fehlt noch)
self.moisture_level = round(client.JSON_Moisture["moisture_level"] - 2.7) / (1 - 2.7)
print(self.moisture_level)
# umrechnen von analogem Wert zu Prozentanteil
print(self.moisture_level)
# update the weight label with the current time
self.moisture_label.setText('Bodenfeuchtigkeit: ' + str(self.moisture_level)[:5] + '%')
def stop_measuring(self):
if client.JSON_Control["measure"]:
client.JSON_Control["measure"] = False
else:
pass
def quit(self):
QtWidgets.QApplication.instance().quit()
client.JSON_Control["exit"] = True
sleep(2)
client.exit = True
client.thread_recv.join()
client.thread_send.join()
client.socket_connection.close()
print("Server connection is closed")
print('exiting...')
sleep(1)
sys.exit()
client = MyClient(1957, 1024, "192.168.86.121")
app = QtWidgets.QApplication()
window = UiDisplay()
window.show()
app.exec()
--------------------------------------------------------
The Server-side:
import sys
from socket import *
from threading import Thread
import pickle
from time import sleep
import Adafruit_ADS1x15
adc_channel_0 = 0
class SoilMoistureSensor:
def __init__(self, gain, sps, dry_voltage, saturated_voltage):
self.adc = Adafruit_ADS1x15.ADS1115()
self.raw_data = None
self.moisture_level = None
# self.voltage = None
self.gain = gain
self.sps = sps
self.dry_voltage = dry_voltage
self.saturated_voltage = saturated_voltage
class MyServer:
def __init__(self, echo_port, buf_size):
self.buf_size = buf_size
self.echo_port = echo_port
self.data_send = None
self.data_recv = None
self.exit = False
self.data_json = None
self.moisture_sensor = SoilMoistureSensor(2, 32, 1, 2.7) # gain, sps, saturated_voltage, dry_voltage
self.JSON_Control = {
"measure": False,
"exit": False
}
self.JSON_Moisture = {
"moisture_level": 0,
}
self.socket_connection = socket(AF_INET, SOCK_STREAM)
self.socket_connection.bind(("", self.echo_port))
self.socket_connection.listen(1)
print("Server gestartet")
print("Name des Hosts: ", gethostname())
print("IP des Hosts: ", gethostbyname(gethostname()))
self.conn, (self.remotehost, self.remoteport) = self.socket_connection.accept()
print("Verbunden mit %s %s " % (self.remotehost, self.remoteport))
# thread for sending
self.thread_send = Thread(target=self.worker_send)
# thread for receiving
self.thread_recv = Thread(target=self.worker_recv)
# thread for checking Json Control
self.thread_check_json_control = Thread(target=self.check_json_control)
# starting Threads
self.thread_send.start()
self.thread_recv.start()
self.thread_check_json_control.start()
def worker_send(self):
while not self.exit:
self.data_send = pickle.dumps(self.JSON_Moisture)
self.conn.send(self.data_send)
sleep(0.5)
def worker_recv(self):
while not self.exit:
self.data_recv = self.conn.recv(self.buf_size)
if self.data_recv is not None:
self.JSON_Control = pickle.loads(self.data_recv)
def measure_moisture(self, channel):
channel = adc_channel_0
self.moisture_sensor.raw_data = self.moisture_sensor.adc.read_adc(
channel, self.moisture_sensor.gain, self.moisture_sensor.sps)
self.JSON_Moisture["moisture_level"] = self.moisture_sensor.raw_data
print(self.moisture_sensor.raw_data)
def stop_connection(self):
self.thread_recv.join()
self.thread_send.join()
self.thread_check_json_control.join()
self.socket_connection.close()
print("Server connection is closed")
print('exiting...')
sys.exit()
def check_json_control(self):
while not self.exit:
if self.JSON_Control["measure"]:
self.measure_moisture(0)
if self.JSON_Control["exit"]:
self.stop_connection()
sleep(0.5)
server = MyServer(1957, 1024)
I´d be ever so grateful for help and I´m incredibly sorry if I´ve disregarded any question conventions. Cheers!