first commit for the sender side
This commit is contained in:
commit
17715b22ad
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.env
|
||||
venv/
|
||||
0
__init__.py
Normal file
0
__init__.py
Normal file
80
client.py
Normal file
80
client.py
Normal file
@ -0,0 +1,80 @@
|
||||
# sender/client.py — TCP socket client, connects to receiver and sends data
|
||||
|
||||
import socket
|
||||
import time
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from config import HOST, PORT, SEND_INTERVAL, ACK_BYTE, RECONNECT_DELAY, BUFFER_SIZE
|
||||
from generator import generate_data
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--id", required=True, help="Device ID")
|
||||
args = parser.parse_args()
|
||||
|
||||
DEVICE_ID = args.id
|
||||
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="[SENDER] %(asctime)s — %(message)s",
|
||||
datefmt="%H:%M:%S"
|
||||
)
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def connect_to_server() -> socket.socket:
|
||||
"""Keep trying to connect until server is available."""
|
||||
while True:
|
||||
try:
|
||||
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
client.connect((HOST, PORT))
|
||||
log.info(f"Connected to server at {HOST}:{PORT}")
|
||||
return client
|
||||
except ConnectionRefusedError:
|
||||
log.warning(f"Server not available. Retrying in {RECONNECT_DELAY}s...")
|
||||
time.sleep(RECONNECT_DELAY)
|
||||
|
||||
|
||||
def run():
|
||||
log.info(f"Sender starting with DEVICE_ID={DEVICE_ID}...")
|
||||
|
||||
while True:
|
||||
client = connect_to_server()
|
||||
|
||||
try:
|
||||
while True:
|
||||
# 1. Generate data string with unique ID
|
||||
data = generate_data(DEVICE_ID)
|
||||
display = data.replace('\0', '\\0')
|
||||
log.info(f"Sending → {display}")
|
||||
|
||||
# 2. Send encoded bytes
|
||||
client.sendall(data.encode('utf-8'))
|
||||
|
||||
# 3. Wait for ACK
|
||||
try:
|
||||
client.settimeout(5.0)
|
||||
ack = client.recv(BUFFER_SIZE)
|
||||
if ack == ACK_BYTE:
|
||||
log.info("ACK received")
|
||||
else:
|
||||
log.warning(f"Unexpected response: {ack}")
|
||||
except socket.timeout:
|
||||
log.error("ACK timeout — server may be down")
|
||||
break
|
||||
|
||||
# 4. Wait before next send
|
||||
time.sleep(SEND_INTERVAL)
|
||||
|
||||
except (ConnectionResetError, BrokenPipeError, OSError) as e:
|
||||
log.error(f"Connection lost: {e}. Reconnecting...")
|
||||
finally:
|
||||
client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
8
config.py
Normal file
8
config.py
Normal file
@ -0,0 +1,8 @@
|
||||
# config.py — shared settings for sender and receiver
|
||||
|
||||
HOST = "127.0.0.1"
|
||||
PORT = 3000
|
||||
SEND_INTERVAL = 5 # seconds between each data send
|
||||
BUFFER_SIZE = 4096
|
||||
ACK_BYTE = b'\x06' # standard ACK control character
|
||||
RECONNECT_DELAY = 3 # seconds before sender retries connection
|
||||
39
generator.py
Normal file
39
generator.py
Normal file
@ -0,0 +1,39 @@
|
||||
# sender/generator.py — generates realistic solar sensor data strings
|
||||
|
||||
import random
|
||||
import time
|
||||
|
||||
|
||||
DOOR_STATES = ["OPEN", "CLOSE"]
|
||||
|
||||
|
||||
def generate_data(device_id: str) -> str:
|
||||
|
||||
ts = int(time.time())
|
||||
sv = round(random.uniform(40.0, 55.0), 1)
|
||||
si = round(random.uniform(0.0, 40.0), 1)
|
||||
sp = random.randint(0, 2200)
|
||||
bv = round(random.uniform(44.0, 58.0), 2)
|
||||
bcur = round(random.uniform(-30.0, 30.0), 1)
|
||||
bsoc = random.randint(0, 100)
|
||||
bsoh = random.randint(80, 100)
|
||||
bt = round(random.uniform(10.0, 50.0), 1)
|
||||
at = round(random.uniform(15.0, 45.0), 1)
|
||||
door = random.choice(DOOR_STATES)
|
||||
|
||||
message = (
|
||||
f"ID={device_id},"
|
||||
f"TS={ts},"
|
||||
f"SV={sv},"
|
||||
f"SI={si},"
|
||||
f"SP={sp},"
|
||||
f"BV={bv},"
|
||||
f"BCUR={bcur},"
|
||||
f"BSOC={bsoc},"
|
||||
f"BSOH={bsoh},"
|
||||
f"BT={bt},"
|
||||
f"AT={at},"
|
||||
f"DOOR={door}"
|
||||
f"\0"
|
||||
)
|
||||
return message
|
||||
Loading…
x
Reference in New Issue
Block a user