-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodel.py
More file actions
251 lines (224 loc) · 8.09 KB
/
Copy pathmodel.py
File metadata and controls
251 lines (224 loc) · 8.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
import paho.mqtt.client as mqtt
import configparser
import os
import random
import sqlite3
######################## HOW TO RUN THE PROGRAM #########################
# #
# In order to run the program you need to install the dependencies #
# After dependencies: #
# > Navigate to the programs folder #
# > Check the configfile and template_dir variables to match the #
# folder where they are located #
# > run on terminal: python view.py #
# > If webpage does not automaticall open: #
# open it manually by navigating to address: http://127.0.0.1:5000/ #
# #
#########################################################################
mqtt_topic_name = 11
devId = -1
state = 'Null'
time = 'Null'
status = {'deviceId':devId, 'state': state, 'time':time}
threadStarted=False
###################### STORE DATA (SCADA) ######################
# AUT840 COURSES FACTORY_DICT ROW_FACTORY
def dict_factory(cursor, row):
d = {}
for idx, col in enumerate(cursor.description):
d[col[0]] = row[idx]
return d
conn = sqlite3.connect(':memory:', check_same_thread=False)
conn.row_factory = dict_factory
c = conn.cursor()
c.execute("DROP TABLE IF EXISTS robot;")
c.execute("""CREATE TABLE IF NOT EXISTS robot (
id INTEGER PRIMARY KEY AUTOINCREMENT,
devId TEXT,
state TEXT,
time TIMESTAMP
);""")
# CREATE A ROBOT -> IF CREATED -> UPDATE
def insert_robot(devId, state, time):
with conn:
c.execute("INSERT INTO robot VALUES (:id, :devId, :state, :time)", {'id': None, 'devId': devId, 'state': state, 'time': time})
#update_robot(rid, devId, state, time)
# READ ROBOTS STATUS BY ID
def get_robots_current_status_by_rid(id):
with conn:
c.execute("SELECT devId, state, time FROM robot WHERE devId=:devId", {'devId': id})
#fetchone = c.fetchone()
fetchall = c.fetchall()
#print(fetchall)
i = len(fetchall)
if i > 0:
last = fetchall[i-1]
#print(last)
return last
else:
return []
# READ ALL ROBOTS STATUSES BY ID
def get_robots_all_statuses_by_rid(id):
with conn:
c.execute("SELECT devId, state, time FROM robot WHERE devId=:devId", {'devId': id})
#fetchone = c.fetchone()
fetchall = c.fetchall()
i = len(fetchall)
if i > 0:
return fetchall
else:
return []
# READ ALL ROBOTS STATUSES BY ID
def get_robots_ALL_by_rid_and_state(id, state):
with conn:
c.execute("SELECT devId, state, time FROM robot WHERE devId=:devId AND state=:state", {'devId': id, 'state':state})
fetchall = c.fetchall()
i = len(fetchall)
if i > 0:
return fetchall
else:
return []
# CREATE A TABLE FOR IDLE STATE OF SPECIFIC ROBOT BY ID
def create_LOG_of_IDLE_by_ID(id):
state = "idle"
sqlstate = f"""CREATE TABLE IF NOT EXISTS {state}_log_{id} (
state TEXT,
time TIMESTAMP);"""
with conn:
c.execute(sqlstate)
update_LOG_of_state_by_ID(id, state)
# CREATE A TABLE FOR DOWN STATE OF SPECIFIC ROBOT BY ID
def create_LOG_of_DOWN_by_ID(id):
state = "down"
sqlstate = f"""CREATE TABLE IF NOT EXISTS {state}_log_{id} (
state TEXT,
time TIMESTAMP);"""
with conn:
if c.execute(sqlstate):
c.execute(sqlstate)
update_LOG_of_state_by_ID(id, state)
else:
pass
# UPDATES THE LOG OF STATE
def update_LOG_of_state_by_ID(id, state):
state_upper = state.upper()
c.execute("""SELECT * FROM robot WHERE devId=:devId AND state=:state""",{'devId': id, 'state':state_upper})
sqlstate = f"""INSERT INTO {state}_log_{id} SELECT state, time FROM robot WHERE devId=? AND state=?"""
values = (id, str(state_upper))
#print(sqlstate, values)
sqlstate2 = f"SELECT * FROM {state}_log_{id}"
#CHECK IF TABLE EXISTS
if c.execute(sqlstate2):
c.execute(sqlstate, values)
#print(c.fetchone())
else:
pass
# FETCH VALUES FROM A LOG TABLE BY ID AND STATE
def get_LOG_of_state_by_ID(id, state):
sqlstate = f"""SELECT * FROM {state}_log_{id}"""
if c.execute(sqlstate):
c.execute(sqlstate)
fetchall = c.fetchall()
return fetchall
else:
print(f"Table: {state}_log_{id} does not exist")
return []
# FETCH ALL SEPERATE STATES THE ROBOT HAS BY ID
def get_robots_unique_states_by_rid(id):
c.execute("""SELECT DISTINCT state FROM robot WHERE devId=:devId""", {'devId': id})
fetchall = c.fetchall()
#print(fetchall)
i = len(fetchall)
if i > 0:
return fetchall
else:
return []
# COUNTS AMOUNT OF STATUSES OF ROBOT BY ID AND STATE
def get_robots_amount_of_of_statues_By_rid_and_status(nID, state):
c.execute("""
SELECT
state,
COUNT(*) AS 'amount'
FROM
robot
WHERE
devId=:devId AND state=:state
""", {'devId': nID, 'state':state})
fetch = c.fetchone()
#print(fetch)
return fetch
# READ ALL ROBOTS
def get_all_robots():
sqlSt="SELECT * FROM robot WHERE 1"
c.execute(sqlSt)
#print(c.fetchall())
return c.fetchall()
# UPDATE ROBOTS VALUES
def update_robot(id, devId, state, time):
with conn:
c.execute("""UPDATE robot
SET devId = :devId, state = :state, time = :time
WHERE id = :id""",
{'id': id, 'devId': devId,'state':state, 'time':time})
# DELETE A ROBOT FROM LIST
def remove_robot(devId):
with conn:
c.execute("""DELETE
from robot
WHERE
id = :id""",
{'devId': devId})
###################### MQTT COMMUNICATION ######################
# GET PATH TO THE CONFIG FILE
# Original Path = C:\Users\Miska\Documents\AUT840\GIT\FASTory\templates
configfile = os.path.abspath(os.path.dirname(__file__))
configfile = os.path.join(configfile,'config.ini')
config = configparser.ConfigParser()
config.sections()
config.read(configfile)
# CONNECT TO BROKER AND DEFINE CLIENT
def connect_mqtt(broker, port, client_id, DEBUG) -> mqtt:
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt.Client(client_id)
client.on_connect = on_connect
client.connect(broker, port)
return client
# SUBSCRIBE TO A TOPIC
def subscribe(client, topic):
global devId,state,time,status
def on_message(client, userdata, msg):
global devId,state,time,status
#print(f"Received {msg.payload.decode()} from {msg.topic} topic")
m_in = json.loads(msg.payload.decode()) #decode json data
#print(m_in)
devId = m_in['deviceId']
state = m_in['state']
time = m_in['time']
insert_robot(devId, state, time) # ADD ROBOT TO SQL
#robots = get_robots_state_by_id(1)
#print(robots['state'])
client.subscribe(topic)
client.on_message = on_message
# RUN THE COMMUNICATION
def run():
DEBUG = 0
# Check MQTT connection with Mosquitto
if DEBUG == 1:
broker = str(config['DEBUG']['mqtt_broker'])
port = int(config['DEBUG']['mqtt_port'])
topic = config['DEBUG']['topic']
client_id = f'python-mqtt-{random.randint(0, 100)}'
# Use Courses MQTT settings
else:
broker = str(config['CONNECTION']['mqtt_broker'])
port = int(config['CONNECTION']['mqtt_port'])
client_id = 'Group-AaroLeeviMiska'
topic = f'ii22/telemetry/{mqtt_topic_name}'
print(f'Connecting to {broker} : {port}')
client = connect_mqtt(broker=broker, port=port, client_id=client_id, DEBUG=DEBUG)
subscribe(client, topic)
client.loop_forever() # Start networking daemon