Here's a complete list of all the files I modified and the specific changes made to implement RFID communication between the charge point and central system:
1. File: requirements.txt
Changes: Added missing dependencies
websockets>=15.0
jsonschema>=4.23.0
pyscard>=2.0.0
PyQt5>=5.15.0
2. File: ui_hori/charge_point.py
Changes: Added RFID data sending functionality
Added imports and path setup:
import sys
import os
# Add parent directory to path to import ocpp module
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
Added RFID sending method:
async def send_rfid_data(self, rfid_uid):
"""Send RFID data to the central system using DataTransfer message"""
try:
request = call.DataTransfer(
vendor_id="ChargingStation",
data=rfid_uid
)
response = await self.call(request)
print(f"RFID data sent to server: {rfid_uid}")
print(f"Server response: {response.status}")
print(f"Server data: {response.data}")
return response
except Exception as e:
print(f"Error sending RFID data: {e}")
return None
3. File: central_system.py
Changes: Added DataTransfer handler to receive and process RFID data
Added import:
from ocpp.v21.enums import Action, DataTransferStatusEnumType
Added RFID data handler:
@on(Action.data_transfer)
def on_data_transfer(self, vendor_id, data, **kwargs):
print(f"=== RFID DATA RECEIVED FROM CLIENT ===")
print(f"Charge Point ID: {self.id}")
print(f"Vendor ID: {vendor_id}")
print(f"RFID UID: {data}")
print(f"Timestamp: {datetime.now(timezone.utc).isoformat()}")
print(f"=====================================")
return call_result.DataTransfer(
status=DataTransferStatusEnumType.accepted,
data="RFID data received successfully"
)
4. File: ui_hori/charging_ui.py
Changes: Major modifications for thread-safe RFID communication and UI updates
Added imports:
try:
import websockets
except ModuleNotFoundError:
print("This example relies on the 'websockets' package.")
print("Please install it by running: ")
print()
print(" $ pip install websockets")
sys.exit(1)
Added worker thread reference to MainWindow:
# Store reference to worker thread for RFID communication
self.worker_thread = None
Modified WorkerThread class:
class WorkerThread(QThread):
rfid_data_signal = pyqtSignal(str) # Signal to send RFID data
def __init__(self):
super().__init__()
self.charge_point_instance = None
self.event_loop = None
self.rfid_queue = asyncio.Queue()
def run(self):
# Run asyncio loop inside this thread
asyncio.run(self.main_with_rfid())
async def main_with_rfid(self):
"""Modified main function that keeps reference to charge point instance"""
self.event_loop = asyncio.get_running_loop()
async with websockets.connect(
"ws://localhost:9000/CP_1", subprotocols=["ocpp2.1"]
) as ws:
print("WebSocket connection established.")
self.charge_point_instance = charge_point.ChargePoint("CP_1", ws)
# Start both the charge point and RFID processing
await asyncio.gather(
self.charge_point_instance.start(),
self.charge_point_instance.send_boot_notification(),
self.process_rfid_queue()
)
async def process_rfid_queue(self):
"""Process RFID data from the queue"""
while True:
try:
rfid_uid = await self.rfid_queue.get()
if self.charge_point_instance:
response = await self.charge_point_instance.send_rfid_data(rfid_uid)
if response and response.data:
# Send server response data to UI thread
self.rfid_data_signal.emit(response.data)
self.rfid_queue.task_done()
except Exception as e:
print(f"Error processing RFID: {e}")
def send_rfid_to_server(self, rfid_uid):
"""Method to send RFID data to server - thread safe"""
if self.event_loop and not self.event_loop.is_closed():
# Schedule the RFID to be added to the queue
asyncio.run_coroutine_threadsafe(
self.rfid_queue.put(rfid_uid),
self.event_loop
)
Modified rfid_read method:
def rfid_read(self):
card_ids = [
"7A4C91E2F5B3",
"D19F73C5A28B",
"3F7A1E9C84D2",
"9B62C4D7A1E8",
"5E1C8A3F9D47",
"B2D47F8C31E9",
"4A9F2C7E5D13",
"E1B47D9C3A52",
"8C2F5B7A1E49",
"F73D29E1C84B"
]
# random card_id
self.UID = random.choice(card_ids)
# self.UID = '92345678901234567890'
self.rfid_timer.stop()
print(f"RFID read: {self.UID}")
# Send RFID data to server if worker thread is available
if self.worker_thread and hasattr(self.worker_thread, 'send_rfid_to_server'):
self.worker_thread.send_rfid_to_server(self.UID)
print(f"RFID data sent to server: {self.UID}")
self.goto_step6()
Added UI update method:
def update_rfid_server_response(self, server_response_data):
"""Update UI with server response data from RFID communication"""
print(f"Received server response: {server_response_data}")
# Update label_5 in step6 with the server response
if hasattr(self, 'ui_step6') and hasattr(self.ui_step6, 'label_5'):
self.ui_step6.label_5.setText(server_response_data)
print(f"Updated UI with server response: {server_response_data}")
Modified main function to connect signal:
# Start thread and store reference in MainWindow
thread_a = WorkerThread()
win.worker_thread = thread_a # Store reference for RFID communication
# Connect signal to update UI with server response
thread_a.rfid_data_signal.connect(win.update_rfid_server_response)
thread_a.start()
5. Created Files:
SETUP_INSTRUCTIONS.md
Complete setup and installation guide
RFID_IMPLEMENTATION.md
Detailed documentation of the RFID implementation
THREAD_SAFETY_FIX.md
Documentation of the thread safety fix for the RuntimeError
SERVER_RESPONSE_UI_UPDATE.md
Documentation of the server response UI update implementation
test_rfid_communication.py
Test script for RFID communication
simple_rfid_test.py
Simple test script for RFID functionality
Summary of Key Changes:
- Fixed missing dependencies - Added jsonschema and pyscard to requirements.txt
- Added RFID sending capability - Implemented DataTransfer message sending in charge_point.py
- Added RFID receiving capability - Implemented DataTransfer handler in central_system.py
- Fixed thread safety issues - Implemented proper thread communication using asyncio queues and PyQt signals
- Added UI updates - Server response now displays in the UI at the specified location
- Maintained existing functionality - All original UI flow and charging simulation remains intact
The implementation enables complete RFID communication flow: RFID read → Send to server → Server processes → Response back to UI → Display in interface.