Skip to content

Commit

Permalink
Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
slafi committed Oct 22, 2019
1 parent ff31f9d commit 1ed0423
Show file tree
Hide file tree
Showing 14 changed files with 377 additions and 382 deletions.
82 changes: 34 additions & 48 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,34 @@
from multiprocessing import Process, Queue
from multiprocessing import Queue

# Import custom subpackages
from core import config, monitor, viewer
from common import utils, logger, recorder, database
from common import utils, logger, recorder

import signal, sys, os
import threading, pkgutil
import time


## Initialize the logger
# Initialize the logger
logger = logger.get_logger('voltazero_monitor')

## Define main thread stop flag
#StopFlag = threading.Event()


def signal_handler(signum, frame):
"""A signal handler which sets the stop flag if a termination signal is triggered
:signum: the signal number
:frame: the stack frame which triggered the signal
"""
logger.info('Stop flag raised. Main thread is stopping...')
#StopFlag.set()

# Define main thread stop flag
# StopFlag = threading.Event()


if __name__ == '__main__':

## Clear console
# Clear console
utils.clear_console()

## Setup stop signal handler
#signal.signal(signal.SIGTERM, signal_handler)
#signal.signal(signal.SIGINT, signal_handler)
#signal.signal(signal.SIGABRT, signal_handler)
#signal.signal(signal.SIGQUIT, signal_handler)
print(f'Main: {os.getpid()}')

## Initialization

logger.info(f'Main PID: {os.getpid()}')

# Initialization
config_file = "./core/config.json"

## Setup telemetry queue
# Setup telemetry queue used by the Monitor and Recorder
q = Queue()

## Read the application config
# Read the application config
appConfig = config.AppConfig(config_file)
rc = appConfig.load_app_config()

Expand All @@ -57,50 +40,53 @@ def signal_handler(signum, frame):
sys.exit()
else:
logger.info(f'App configuration loaded and parsed successfully.')
## Establish connectivity to the MQTT broker

# Start the Monitor and establish connection to the MQTT broker
pmonitor = monitor.Monitor(appConfig, q, client_id="cp100")
pmonitor.start()

## Initialize and start database recorder
# Initialize and start database recorder
trecorder = recorder.Recorder(q, appConfig)
trecorder.start()

## Start viewer
viewer = viewer.Viewer(appConfig, window_title='Sensors data')
viewer.start()
# Start viewer if required
if(appConfig.no_viewer):
viewer = viewer.Viewer(appConfig, window_title='Sensors data')
viewer.start()
else:
logger.info('The viewer is disabled.')

## Sleep main thread
# Sleep main thread
while True:
try:
time.sleep(500)
except KeyboardInterrupt:
print("Stopping all threads and processes...")
break
logger.info("Stopping all threads and processes...")
break

try:

## Stop the monitor process
# Stop the monitor process
pmonitor.stop()
pmonitor.join()

## Stop the recorder thread
# Stop the recorder thread
trecorder.stop()
trecorder.join()

## stop viewer
viewer.stop()
viewer.join()
# stop viewer if already started
if(appConfig.no_viewer):
viewer.stop()
viewer.join()

except Exception as e:
print(f'Exception: {str(e)}')

## For debug, check the data remaining in the queue
# For debug, check the data remaining in the queue
# Normally, no data should remain in q
data = []

while not q.empty():
data.append(q.get())

print(data)



96 changes: 45 additions & 51 deletions common/database.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@

from sqlite3 import Error
from datetime import datetime

from common import utils, logger
from common import utils
from core import telemetry

from datetime import datetime

import sqlite3
import os, sys, inspect
import os
import logging


### Initialize logger for the module
# Initialize logger for the module
logger = logging.getLogger('voltazero_monitor')


Expand All @@ -23,18 +22,18 @@ def check_connection(db_filename, db_path=""):
:return: True if success or False if failure or an exception arises
"""
try:
if db_filename != None:
if db_filename is not None:
db_name = os.path.join(db_path, db_filename)
connection_handler = connect(db_name)
if connection_handler != None:
if connection_handler is not None:
return True
else:
return False
else:
return False

except sqlite3.Error as e:
logger.error('Database connection error: {0}'.format(e))
logger.error('Database connection error: {0}'.format(e))
return False
finally:
if connection_handler:
Expand All @@ -54,23 +53,19 @@ def connect(db_filename, db_path=""):
db_name = os.path.join(db_path, db_filename)
connection_handler = sqlite3.connect(db_name)
connection_handler.text_factory = sqlite3.OptimizedUnicode
#print(sqlite3.version)

return connection_handler
except sqlite3.Error as e:
logger.error('Database connection error: {0}'.format(e))
logger.error('Database connection error: {0}'.format(e))
return None
"""finally:
if connection_handler:
connection_handler.close()"""


def create_datatable(connection_handler, table_name="data"):
"""
Creates a new SQLite database and datatable where the telemetry will be stored
:param connection_handler: the Connection object
:param table_name: the data table name
:return: 0 if succes, -1 if the connection handler is None and -2 if exception arises
""" Creates a new SQLite database and datatable where the telemetry will be stored
:param connection_handler: the Connection object
:param table_name: the data table name
:return: 0 if succes, -1 if the connection handler is None and -2 if exception arises
"""
try:
sql = f"""
Expand All @@ -87,9 +82,9 @@ def create_datatable(connection_handler, table_name="data"):
);
"""

if connection_handler == None:
if connection_handler is None:
return -1

connection_handler.cursor().execute(sql)
return 0

Expand All @@ -99,12 +94,12 @@ def create_datatable(connection_handler, table_name="data"):


def insert_telemetry_data(connection_handler, data, table_name="data"):
"""
Query the database to insert a list of telemetry records in the database
:param connection_handler: the Connection object
:param data: the list of telemetry records
:param table_name: the data table name
:return: count of inserted records or -1 if exception arises
""" Query the database to insert a list of telemetry records in the database
:param connection_handler: the Connection object
:param data: the list of telemetry records
:param table_name: the data table name
:return: count of inserted records or -1 if exception arises
"""
try:
cursor = connection_handler.cursor()
Expand All @@ -123,13 +118,13 @@ def insert_telemetry_data(connection_handler, data, table_name="data"):
if i == len(data)-1:
sqlite_insert_query = f"{sqlite_insert_query};"
else:
sqlite_insert_query = f"{sqlite_insert_query},"
sqlite_insert_query = f"{sqlite_insert_query},"

count = cursor.execute(sqlite_insert_query)
connection_handler.commit()
cursor.close()

logger.debug(f"Inserted rows: {cursor.rowcount}")
logger.debug(f"Data rows inserted: {cursor.rowcount}")
return count

except sqlite3.Error as error:
Expand All @@ -138,20 +133,21 @@ def insert_telemetry_data(connection_handler, data, table_name="data"):


def retrieve_data(connection_handler, time_window, table_name):
"""
Query the database to get all telemetry records in a specified time window starting now
:param connection_handler: the Connection object
:param time_window: the time interval for the records lookup
:param table_name: the data table name
:return: list of telemetry records or None if exception arises
""" Query the database to get all telemetry records in a specified
time window starting now
:param connection_handler: the Connection object
:param time_window: the time interval for the records lookup
:param table_name: the data table name
:return: list of telemetry records or None if exception arises
"""
try:
timestamp = datetime.fromtimestamp(utils.get_unix_timestamp() - time_window).strftime("%Y/%m/%d %H:%M:%S")
cursor = connection_handler.cursor()
cursor.execute(f"SELECT * FROM {table_name} WHERE timestamp >= ? ORDER BY timestamp ASC", (timestamp,))

rows = cursor.fetchall()

data = []
for row in rows:
tlm = telemetry.Telemetry(timestamp=row[7], t0=row[1], t1=row[2], th=row[3], bz=row[6], ls=row[5], ir=row[4], id=f"item_{row[0]}")
Expand All @@ -166,15 +162,15 @@ def retrieve_data(connection_handler, time_window, table_name):


def check_if_datatable_exists(connection_handler, table_name="data"):
"""
Query the database to check if the data table already eaxists
:param connection_handler: the Connection object
:param table_name: the data table name
:return: True if exists and False if does not exist or exception arises
""" Query the database to check if the data table already eaxists
:param connection_handler: the Connection object
:param table_name: the data table name
:return: True if exists and False if does not exist or exception arises
"""
try:

### Check the list of tables
# Check the list of tables
cursor = connection_handler.cursor()
cursor.execute(f"SELECT name FROM sqlite_master WHERE type='table';")
list_of_tables = cursor.fetchall()
Expand All @@ -184,7 +180,7 @@ def check_if_datatable_exists(connection_handler, table_name="data"):
for item in list_of_tables:
if table_name == item[0]:
return True
else :
else:
return False

except sqlite3.Error as error:
Expand All @@ -194,17 +190,15 @@ def check_if_datatable_exists(connection_handler, table_name="data"):

# Closes the ongoing database connection if still alive
def disconnect(connection_handler):
"""
Closes a current database connection
:param connection_handler: the Connection object
:return: 0 if success and -1 if an exception arises
""" Closes a current database connection
:param connection_handler: the Connection object
:return: 0 if success and -1 if an exception arises
"""
try:
if connection_handler != None:
if connection_handler is not None:
connection_handler.close()
return 0
except sqlite3.Error as e:
logger.error('Database disconnection error: {0}'.format(e))
return -1


5 changes: 0 additions & 5 deletions common/itimer/__init__.py

This file was deleted.

22 changes: 0 additions & 22 deletions common/itimer/cleanup.py

This file was deleted.

Loading

0 comments on commit 1ed0423

Please sign in to comment.