-
Notifications
You must be signed in to change notification settings - Fork 37
Configfiles to support different operational modes #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
15e0412
d05b000
6e324ef
fc5e468
4b88e1f
45c6044
0b5dd84
eedd544
77b31b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ | |
|
|
||
|
|
||
| application = Flask(__name__) | ||
| application.config.from_pyfile('config/chibio_default.cfg', silent=True) | ||
| application.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 #Try this https://stackoverflow.com/questions/23112316/using-flask-how-do-i-modify-the-cache-control-header-for-all-output/23115561#23115561 | ||
|
|
||
| lock=Lock() | ||
|
|
@@ -34,6 +35,7 @@ | |
| 'presentDevices' : { 'M0' : 0,'M1' : 0,'M2' : 0,'M3' : 0,'M4' : 0,'M5' : 0,'M6' : 0,'M7' : 0}, | ||
| 'Version' : {'value' : 'Turbidostat V3.0'}, | ||
| 'DeviceID' : '', | ||
| 'DeviceName': '', | ||
| 'time' : {'record' : []}, | ||
| 'LEDA' : {'WL' : '395', 'default': 0.1, 'target' : 0.0, 'max': 1.0, 'min' : 0.0,'ON' : 0}, | ||
| 'LEDB' : {'WL' : '457', 'default': 0.1, 'target' : 0.0, 'max': 1.0, 'min' : 0.0,'ON' : 0}, | ||
|
|
@@ -370,10 +372,9 @@ def initialise(M): | |
| scanDevices(M) | ||
| if(sysData[M]['present']==1): | ||
| turnEverythingOff(M) | ||
| print(str(datetime.now()) + " Initialised " + str(M) +', Device ID: ' + sysData[M]['DeviceID']) | ||
| print(str(datetime.now()) + " Initialised " + str(M) + ', (' + sysData[M]['DeviceName'] + ') Device ID: ' | ||
| + sysData[M]['DeviceID']) | ||
|
|
||
|
|
||
|
|
||
|
|
||
| def initialiseAll(): | ||
| # Initialisation function which runs at when software is started for the first time. | ||
|
|
@@ -382,6 +383,11 @@ def initialiseAll(): | |
| time.sleep(2.0) #This wait is to allow the watchdog circuit to boot. | ||
| print(str(datetime.now()) + ' Initialising devices') | ||
|
|
||
| check_config_value(config_key='TWO_PUMPS_PER_DEVICE', default_value=False) | ||
| check_config_value(config_key='NUMBER_OF_OD_MEASUREMENTS', default_value=4) | ||
| check_config_value(config_key='DEVICE_COMM_FAILURE_THRESHOLD', default_value=10) | ||
|
|
||
|
|
||
| for M in ['M0','M1','M2','M3','M4','M5','M6','M7']: | ||
| initialise(M) | ||
| scanDevices("all") | ||
|
|
@@ -405,7 +411,13 @@ def turnEverythingOff(M): | |
|
|
||
| I2CCom(M,'DAC',0,8,int('00000000',2),int('00000000',2),0)#Sets all DAC Channels to zero!!! | ||
| setPWM(M,'PWM',sysItems['All'],0,0) | ||
| setPWM(M,'Pumps',sysItems['All'],0,0) | ||
|
|
||
| if application.config['TWO_PUMPS_PER_DEVICE']: | ||
| chibios_to_shut_down = [0, 1, 2, 3] | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's call the variable chibios_w_pumps |
||
| else: | ||
| chibios_to_shut_down = [0, 1, 2, 4, 5, 6, 7] | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. number 3 is missing! |
||
| if int(M[1]) in chibios_to_shut_down: | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's use f-string instead! printf(f'M{number}') in number |
||
| setPWM(M=M, device='Pumps', channels=sysItems['All'], fraction=0, ConsecutiveFails=0) | ||
|
|
||
| SetOutputOn(M,'Stir',0) | ||
| SetOutputOn(M,'Thermostat',0) | ||
|
|
@@ -584,12 +596,12 @@ def SetOutputOn(M,item,force): | |
| if (force==1): | ||
| sysData[M][item]['ON']=1 | ||
| SetOutput(M,item) | ||
| return ('', 204) | ||
| return ('', 204) | ||
|
|
||
| elif(force==0): | ||
| sysData[M][item]['ON']=0; | ||
| SetOutput(M,item) | ||
| return ('', 204) | ||
| return ('', 204) | ||
|
|
||
| #Elsewise this is doing a flip operation (i.e. changes to opposite state to that which it is currently in) | ||
| if (sysData[M][item]['ON']==0): | ||
|
|
@@ -681,7 +693,27 @@ def PumpModulation(M,item): | |
| global sysData | ||
| global sysItems | ||
| global sysDevices | ||
|
|
||
|
|
||
| if application.config['TWO_PUMPS_PER_DEVICE']: | ||
| pump_mapping = {'M4': 'M0', 'M5': 'M1', 'M6': 'M2', 'M7': 'M3'} | ||
| if int(M[1]) in [0, 1, 2, 3]: | ||
| if item == 'Pump1' or item == 'Pump2': | ||
| MB = M | ||
| itemB = item | ||
| elif item == 'Pump3' or item == 'Pump4': | ||
| sysData[M][item]['ON'] = 0 | ||
| return | ||
| else: | ||
| if item == 'Pump1' or item == 'Pump2': | ||
| MB = pump_mapping[M] | ||
| itemB = 'Pump' + str(int(item[4])+2) | ||
| elif item == 'Pump3' or item == 'Pump4': | ||
| sysData[M][item]['ON'] = 0 | ||
| return | ||
| else: | ||
| MB = M | ||
| itemB = item | ||
|
|
||
| sysDevices[M][item]['threadCount']=(sysDevices[M][item]['threadCount']+1)%100 #Index of the particular thread running. | ||
| currentThread=sysDevices[M][item]['threadCount'] | ||
|
|
||
|
|
@@ -690,10 +722,10 @@ def PumpModulation(M,item): | |
|
|
||
| if (abs(sysData[M][item]['target']*sysData[M][item]['ON'])!=1 and currentThread==sysDevices[M][item]['threadCount']): #In all cases we turn things off to begin | ||
| sysDevices[M][item]['active']=1 | ||
| setPWM(M,'Pumps',sysItems[item]['In1'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(M,'Pumps',sysItems[item]['In2'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(M,'Pumps',sysItems[item]['In1'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(M,'Pumps',sysItems[item]['In2'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In1'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In2'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In1'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In2'],0.0*float(sysData[M][item]['ON']),0) | ||
| sysDevices[M][item]['active']=0 | ||
| if (sysData[M][item]['ON']==0): | ||
| return | ||
|
|
@@ -711,23 +743,23 @@ def PumpModulation(M,item): | |
|
|
||
| if (sysData[M][item]['target']>0 and currentThread==sysDevices[M][item]['threadCount']): #Turning on pumps in forward direction | ||
| sysDevices[M][item]['active']=1 | ||
| setPWM(M,'Pumps',sysItems[item]['In1'],1.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(M,'Pumps',sysItems[item]['In2'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In1'],1.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In2'],0.0*float(sysData[M][item]['ON']),0) | ||
| sysDevices[M][item]['active']=0 | ||
| elif (sysData[M][item]['target']<0 and currentThread==sysDevices[M][item]['threadCount']): #Or backward direction. | ||
| sysDevices[M][item]['active']=1 | ||
| setPWM(M,'Pumps',sysItems[item]['In1'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(M,'Pumps',sysItems[item]['In2'],1.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In1'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In2'],1.0*float(sysData[M][item]['ON']),0) | ||
| sysDevices[M][item]['active']=0 | ||
|
|
||
| time.sleep(Ontime) | ||
|
|
||
| if(abs(sysData[M][item]['target'])!=1 and currentThread==sysDevices[M][item]['threadCount']): #Turning off pumps at appropriate time. | ||
| sysDevices[M][item]['active']=1 | ||
| setPWM(M,'Pumps',sysItems[item]['In1'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(M,'Pumps',sysItems[item]['In2'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(M,'Pumps',sysItems[item]['In1'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(M,'Pumps',sysItems[item]['In2'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In1'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In2'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In1'],0.0*float(sysData[M][item]['ON']),0) | ||
| setPWM(MB,'Pumps',sysItems[itemB]['In2'],0.0*float(sysData[M][item]['ON']),0) | ||
| sysDevices[M][item]['active']=0 | ||
|
|
||
| Time2=datetime.now() | ||
|
|
@@ -1336,7 +1368,7 @@ def I2CCom(M,device,rw,hl,data1,data2,SMBUSFLAG): | |
|
|
||
| global sysDevices | ||
| if(sysData[M]['present']==0): #Something stupid has happened in software if this is the case! | ||
| print(str(datetime.now()) + ' Trying to communicate with absent device - bug in software!. Disabling hardware and software!') | ||
| print(str(datetime.now()) + ' Trying to communicate with M%s absent device - bug in software!. Disabling hardware and software!' % M) | ||
| sysItems['Watchdog']['ON']=0 #Basically this will crash all the electronics and the software. | ||
| out=0 | ||
| tries=-1 | ||
|
|
@@ -1420,11 +1452,12 @@ def I2CCom(M,device,rw,hl,data1,data2,SMBUSFLAG): | |
| out=0 | ||
| sysData[M]['present']=0 | ||
| tries=-1 | ||
| if tries>10: #In this case something else has gone wrong, so we panic. | ||
| if tries >= application.config['DEVICE_COMM_FAILURE_THRESHOLD']: #In this case something else has gone wrong, so we panic. | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this! |
||
| sysItems['Watchdog']['ON']=0 #Basically this will crash all the electronics and the software. | ||
| out=0 | ||
| sysData[M]['present']=0 | ||
| print('Failed to communicate to a device 10 times. Disabling hardware and software!') | ||
| print('Failed to communicate to a device %d times. Disabling hardware and software!' % | ||
| application.config['DEVICE_COMM_FAILURE_THRESHOLD']) | ||
| tries=-1 | ||
| os._exit(4) | ||
|
|
||
|
|
@@ -2066,13 +2099,13 @@ def runExperiment(M,placeholder): | |
|
|
||
| sysData[M]['OD']['Measuring']=1 #Begin measuring - this flag is just to indicate that a measurement is currently being taken. | ||
|
|
||
| #We now meausre OD 4 times and take the average to reduce noise when in auto mode! | ||
| ODV=0.0 | ||
| for i in [0, 1, 2, 3]: | ||
| # We now measure OD N times and take the average to reduce noise when in auto mode! | ||
| ODV = 0.0 | ||
| for _ in range(0, application.config['NUMBER_OF_OD_MEASUREMENTS']): | ||
| MeasureOD(M) | ||
| ODV=ODV+sysData[M]['OD']['current'] | ||
| time.sleep(0.25) | ||
| sysData[M]['OD']['current']=ODV/4.0 | ||
| sysData[M]['OD']['current'] = ODV/float(application.config['NUMBER_OF_OD_MEASUREMENTS']) | ||
|
|
||
| MeasureTemp(M,'Internal') #Measuring all temperatures | ||
| MeasureTemp(M,'External') | ||
|
|
@@ -2187,7 +2220,14 @@ def runExperiment(M,placeholder): | |
| addTerminal(M,'Experiment Stopped') | ||
|
|
||
|
|
||
|
|
||
| def check_config_value(config_key, default_value, critical=False): | ||
| if config_key not in application.config.keys(): | ||
| if critical: | ||
| raise ValueError('config value for %s was not found, it must be set for safe operations' % config_key) | ||
| application.config[config_key] = default_value | ||
| application.logger.warning('config value %s was not found and set to default: %d' % (config_key, default_value)) | ||
| else: | ||
| application.logger.info('config found: %s=%s' % (config_key, application.config[config_key])) | ||
|
|
||
| if __name__ == '__main__': | ||
| initialiseAll() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| NUMBER_OF_OD_MEASUREMENTS = 4 | ||
| TWO_PUMPS_PER_DEVICE = False | ||
| DEVICE_COMM_FAILURE_THRESHOLD = 10 | ||
| CONTINUOUS_STIRRING = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove device name feature