-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathext_process_gh.py
255 lines (206 loc) · 9.68 KB
/
ext_process_gh.py
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
252
253
254
# -*- coding: utf-8 -*-
#import sys
import logging
import time
import abc_def
import Tkinter as Tk
# -------------- local libs ------------------
# sys.path.append( "../rshlib" )
import misc_stuff
import smart_terminal
#this does the data processing and csv file save for the green_house application
#some of operation comes from parameters
# ================= Class =======================
#
class GHCSVProcessing( abc_def.ABCProcessing ):
"""
This extension monitors and processes data from the arduino greenhouse monitor
there is little data processing involved, just read and save.
"""
# ------------------------------------------
def __init__( self, controller ):
"""
create processing class
call: gui thread
args: controller class the main app
ret: zip
"""
self.controller = controller
self.parameters = controller.parameters
self.helper_thread = controller.helper_thread
self.logger = logging.getLogger( self.controller.logger_id + ".GHCSVProcessing")
self.logger.debug( "in class GHCSVProcessing init" ) # logger not currently used by here
self.time = time.time() # set in set_time -- taken as same for all measurements
self.next_csv_line = ""
#self.last_time = None
self.last_time = time.time()
# not in parameters because not so easily changed these just validate recieved data
# these are the numbers of measurements of each type.
# not all are implemented
self.no_temps = 2
self.no_humids = 2
self.no_lights = 1
self.no_doors = 4
# ----------------------------------------
def add_gui( self, parent, ):
"""
call: gui thread
args: parent = the parent frame for this frame
ret: the frame we have created.
additional gui for this extension
creates a couple of buttons with call backs to methods within this class, which
also run in the GUI thread
"""
self.button_var = Tk.IntVar() # must be done after root for Tkinter is created
ret_frame = Tk.Frame( parent, width = 600, height=200, bg = self.parameters.bk_color, relief = Tk.RAISED, borderwidth=1 )
self.button_action_list = misc_stuff.ButtonActionList( ) # this is a gui construction helper that helps manage the call back functions
# ------------------------------------------
self.button_action_list.create_action( "Helper: Find and Monitor Arduino", self.cb_find_and_monitor_arduino )
self.button_action_list.create_action( "Interrupt Helper", self.cb_end_helper )
a_frame = Tk.Frame( ret_frame, width = 600, height=200, bg = "gray", relief = Tk.RAISED, borderwidth=1 )
a_frame.pack( side = Tk.LEFT)
self.button_action_list.create_place_in_frame( a_frame )
return ret_frame
# ----------------------------------------
def monitor_arduino_loop( self ):
"""
assumes port opened successfully
infinite loop
call: run in ht not controller
ret: only on failure, probably should be exception
"""
# typically stat functions with this sort of thing
helper_thread = self.controller.helper_thread
# gui = self.controller.gui
# helper_label = gui.helper_label no direct access to gui
#helper_thread.print_info_string( "Starting Arduino Monitoring..." )
helper_thread.post_to_queue( "info", None, "Starting Arduino Monitoring..." ) # rec send info
#helper_thread.release_gui_for( 5 )
# beware long v response wait a bit here say 10 sec
helper_thread.sleep_ht_for( 10 )
while True:
self.set_time( )
send_rec_wait = 10. # a long time should slow down only if a problem
rec_data = helper_thread.send_receive( "a", send_rec_wait ) # throw except if times out
ix = rec_data.find( "ok", 0, len( rec_data ) )
if ix == -1:
msg = "failed to find ok got: >>>" + rec_data + "<<<"
self.logger.error( msg )
print( msg ) # !! use log print in recive area
# need to inform gui and probably throw exception !!
return False # probably should be infinite except
#self.controller.send( "t\n" )
rec_data = helper_thread.send_receive( "t", send_rec_wait ) # throw except if times out
self.process_temp_line( rec_data )
rec_data = helper_thread.send_receive( "h", send_rec_wait ) # throw except if times out
self.process_humid_line( rec_data )
helper_thread.sleep_ht_for( 10. )
# ----------------------------------------
def find_and_monitor_arduino( self ):
"""
call: ht
"""
# typically start with these 2 lines
helper_thread = self.controller.helper_thread
#gui = self.controller.gui
#helper_label = gui.helper_label
helper_thread.sleep_ht_with_msg_for( 10, "Beginning find and Monitor Arduino... ", 5, True )
ok, a_port = helper_thread.find_arduino( )
#helper_thread.release_gui_for( 0 )
if ok:
#helper_label.config( text = "found arduino on " + a_port ) # helper_thread
#self.controller.gui.show_item( "helper_info", "found arduino on " + a_port )
helper_thread.print_info_string( "found Arduino on " + a_port )
self.monitor_arduino_loop()
else:
#helper_label.config( text = "arduino not found " )
#self.controller.gui.show_item( "helper_info", "arduino not found " )
helper_thread.print_info_string( "Error: Arduino not found -- looked for " + self.parameters.arduino_version ) # + a_port )
return
# ------------------------------------------
def set_time( self, ):
"""
set the aquisition time of the data init the csv line
when is this ever called or updated: aquire data
"""
self.time = time.time()
self.next_csv_line = str( self.time )
# ------------------------------------------
def process_temp_line( self, line ):
"""
process a line containing temperature values
how to handle failure??
note call to save data, in process... after last data item is read
!! improve error management
"""
ok, values = self.helper_thread.parse_out_floats( line )
if not ok:
self.logger.error("error in parse return value for temp >>>" + line + "<<<" )
return # NEED better handling here
#else:
#return
if len( values ) != self.no_temps :
self.logger.error("error in parse len of values for temp : " + str( len( values )) + " >>>" + line + "<<<" )
return
for ix_value, i_value in enumerate( values ):
self.next_csv_line += "," + str( i_value )
# ------------------------------------------
def process_humid_line( self, line ):
"""
repeat stuff from temp, humit......
"""
ok, values = self.helper_thread.parse_out_floats( line )
#print values
if not ok:
self.logger.error( "error in parse return value for humid" + line + "<<<" )
return # NEED better handling here
if len( values ) != self.no_temps :
self.logger.error("error in parse len of values for humid: " + str( len( values )) + " >>>" + line + "<<<" )
return
for ix_value, i_value in enumerate( values ):
self.next_csv_line += "," + str( i_value )
self.controller.helper_thread.write_csv( self.next_csv_line )
print( self.next_csv_line )
#self.save_data() # best call after the last item of data is acquired, or as part of next acquire
# ------------------------------------------
def process_light_line( self, line ):
"""
not implemented
repeat stuff from temp, humit......
"""
#self.logger.debug( "process_light_line " + line )
pass # enough for testing temp
# ------------------------------------------
def process_door_line( self, line ):
"""
not implemented
repeat stuff from temp, humit......
"""
#self.logger.debug( "process_door_line " + line )
pass # enough for testing temp
#----------------------------------------------
def cb_find_and_monitor_arduino( self, a_list ):
"""
button call back from gui
call: gui thread
calls function in the helper thread by using the controller to post the function over to the helper thread
"""
self.controller.post_to_queue( "call", self.find_and_monitor_arduino, ( ) )
# # -------------------------------------------------
# def cb_test_test_ports( self, ignore ):
#
# self.controller.post_to_queue( "call", self.controller.helper_thread.find_arduino , ( ) )
# -------------------------------------------------
def cb_end_helper( self, ignore ):
self.controller.post_to_queue( "call", self.controller.helper_thread.end_helper , ( ) )
# ----------------------------------------------------------
#import test_controller
if __name__ == '__main__':
"""
call main app from this file
"""
print( "" )
print( " ========== starting SmartTerminal from gr_csv_processing.py ==============" )
import smart_terminal
a_app = smart_terminal.SmartTerminal( )
# ======================= eof ======================================