Skip to content

Instantly share code, notes, and snippets.

@craigderington
Created March 12, 2019 13:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save craigderington/207d0696e165f3b6c6eacdbb20e62945 to your computer and use it in GitHub Desktop.
Save craigderington/207d0696e165f3b6c6eacdbb20e62945 to your computer and use it in GitHub Desktop.
Python3 Socket Server - Main App
#!.env/bin/python
# -*- coding: utf-8 -*-
import socket
import sys
from db import db_session
from decoder import inspect_header, decode_header, decode_readings
from datetime import datetime
from models import Tx, TxHeader, TxReading
from sqlalchemy import exc
def main():
"""
The main program for the Python Socket Server.
Receive datastream. Detect and Decode Header.
Create data transmission readings in the database
:return: data obj
"""
while True:
# wait
print('Hi. Please send me some data.')
try:
# accept the socket
connection, client_address = s.accept()
print('{} from client {}'.format(connection, client_address))
# receive the data in small chunks
while True:
# our data obj in 1024 byte chunks
data = connection.recv(1024)
if data:
tx = data.hex()
# set the header values to determine the message type
header = inspect_header(tx[:34], 2)
# return decoded data as an ordered dictionary
decoded = decode_header(header)
# check to see if we have a decoded data object
if decoded:
# create a new tx data object
try:
tx = Tx(
timestamp=datetime.now(),
raw_data=str(data)
)
# add, commit and flush
db_session.add(tx)
db_session.commit()
db_session.flush()
# new ID from our tx
tx_id = tx.id
# set the decoded header to a list obj
items = list(decoded.items())
# access the list members
product_type = items[0][1]
hardware_rev = items[1][1]
firmware_rev = items[2][1]
contact_reason = items[3][1]
alarm_status = items[4][1]
imei = items[5][1]
gsm_rssi = items[6][1]
battery_status = items[7][1]
message_type = items[8][1]
payload_len = items[9][1]
# print a few vars from the list for debugging
print('Decoded Header: {}'.format(decoded))
print('Items from List: {}'.format(items))
print('Product Type: {}'.format(product_type))
print('Message Type: {}'.format(message_type))
print('IMEI: {}'.format(imei))
print('Payload Length: {}'.format(payload_len))
# write our message header and include the new tx_id
try:
tx_header = TxHeader(
tx_id=tx_id,
timestamp=datetime.now(),
product_type=product_type,
hardware_rev=hardware_rev,
firmware_rev=firmware_rev,
contact_reason=contact_reason,
alarm_status=alarm_status,
gsm_rssi=gsm_rssi,
battery_status=battery_status,
imei=imei,
message_type=message_type,
payload_len=payload_len
)
# add new tx_header obj, commit and flush
db_session.add(tx_header)
db_session.commit()
db_session.flush()
# assign new tx_header.id to variable for tx readings
tx_header_id = tx_header.id
# begin processing the readings
readings_data = data[52:]
# if the data contains a comma and Z=, strip it off
if ',Z=' in readings_data:
clean_data = readings_data.split(',Z=')
readings_data = clean_data[0]
# continue to process the tx data readings
# readings returns a list of 8 byte value to convert
for _ in range(payload_len - 1):
readings = inspect_header(readings_data, 8)
# create our tx readings database records for the radio
for reading in readings:
# decode the reading
decoded_reading = decode_readings(reading)
# insert to database
tx_reading = TxReading(
tx_id=tx_id,
tx_header_id=tx_header_id,
timestamp=decoded_reading.timestamp,
distance=decoded_reading.distance,
src=decoded_reading.src,
rssi=decoded_reading.rssi,
temperature=decoded_reading.temperature
)
# commit to the database
db_session.add(tx_reading)
db_session.commit()
# dump the readings values to the console
print('Tx Header ID: {}'.format(tx_header_id))
print('Tx Reading Data: {}'.format(readings_data))
continue
# inner database exception
except exc.SQLAlchemyError as err:
print('Database returned error: {}'.format(str(err)))
# outer database exception
except exc.SQLAlchemyError as err:
print('Database returned error: {}'.format(str(err)))
# incoming data stream could not be decoded
# close the connection
else:
print('The data in the buffer could not be decoded. Aborting connection.')
print('Data: {}'.format(tx))
connection.close()
# end of data from client
else:
print('No more data from {}'.format(client_address))
break
# socket error
except socket.error as socket_err:
print('Socket returned error: {}'.format(socket_err))
sys.exit(1)
if __name__ == '__main__':
"""
Start the Python Socket Server and Listen for Connections.
Network Receiver Listens on Port 9060
"""
# create the socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# bind the socket to the port
server_address = '0.0.0.0'
# should be socket.gethostname()
port = 8060
# bind the server address
s.bind((server_address, port))
# flash a server message to console
print('Socket server starting up... listening on {}, Port: {}'.format(server_address, port))
# listen for incoming connections
s.listen(1)
# call main program
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment