From e44de8a1a70b6691170bf42fc16000024c5fc9c6 Mon Sep 17 00:00:00 2001 From: MAKOMO Date: Mon, 13 Nov 2023 20:00:42 +0100 Subject: [PATCH] adds internal special events API --- src/artisanlib/canvas.py | 114 +++++++++++++++-------------- src/artisanlib/events.py | 9 ++- src/artisanlib/main.py | 55 ++++++-------- src/artisanlib/roast_properties.py | 53 +++++--------- 4 files changed, 103 insertions(+), 128 deletions(-) diff --git a/src/artisanlib/canvas.py b/src/artisanlib/canvas.py index 9c1df766a..a4eeddd41 100644 --- a/src/artisanlib/canvas.py +++ b/src/artisanlib/canvas.py @@ -218,7 +218,7 @@ class tgraphcanvas(FigureCanvas): 'extralinewidths1', 'extralinewidths2', 'extramarkers1', 'extramarkers2', 'extramarkersizes1', 'extramarkersizes2', 'devicetablecolumnwidths', 'extraNoneTempHint1', 'extraNoneTempHint2', 'plotcurves', 'plotcurvecolor', 'overlapList', 'tight_layout_params', 'fig', 'ax', 'delta_ax', 'legendloc', 'legendloc_pos', 'onclick_cid', 'oncpick_cid', 'ondraw_cid', 'rateofchange1', 'rateofchange2', 'flagon', 'flagstart', 'flagKeepON', 'flagOpenCompleted', 'flagsampling', 'flagsamplingthreadrunning', - 'manuallogETflag', 'zoom_follow', 'alignEvent', 'compareAlignEvent', 'compareEvents', 'compareET', 'compareBT', 'compareDeltaET', 'compareDeltaBT', 'compareMainEvents', 'compareBBP', 'compareRoast', + 'manuallogETflag', 'zoom_follow', 'alignEvent', 'compareAlignEvent', 'compareEvents', 'compareET', 'compareBT', 'compareDeltaET', 'compareDeltaBT', 'compareMainEvents', 'compareBBP', 'compareRoast', 'compareExtraCurves1', 'compareExtraCurves2', 'replayType', 'replayedBackgroundEvents', 'beepedBackgroundEvents', 'roastpropertiesflag', 'roastpropertiesAutoOpenFlag', 'roastpropertiesAutoOpenDropFlag', 'title', 'title_show_always', 'ambientTemp', 'ambientTempSource', 'ambient_temperature_device', 'ambient_pressure', 'ambient_pressure_device', 'ambient_humidity', 'ambient_humidity_device', 'elevation', 'temperaturedevicefunctionlist', 'humiditydevicefunctionlist', 'pressuredevicefunctionlist', 'moisture_greens', 'moisture_roasted', @@ -226,7 +226,7 @@ class tgraphcanvas(FigureCanvas): 'darkCut_flag', 'drops_flag', 'oily_flag', 'uneven_flag', 'tipping_flag', 'scorching_flag', 'divots_flag', 'timex', 'temp1', 'temp2', 'delta1', 'delta2', 'stemp1', 'stemp2', 'tstemp1', 'tstemp2', 'ctimex1', 'ctimex2', 'ctemp1', 'ctemp2', 'unfiltereddelta1', 'unfiltereddelta2', 'unfiltereddelta1_pure', 'unfiltereddelta2_pure', 'on_timex', 'on_temp1', 'on_temp2', 'on_ctimex1', 'on_ctimex2', 'on_ctemp1', 'on_ctemp2','on_tstemp1', 'on_tstemp2', 'on_unfiltereddelta1', - 'on_unfiltereddelta2', 'on_delta1', 'on_delta2', 'on_extratemp1', 'on_extratemp2', 'on_extratimex', 'on_extractimex1', 'on_extractemp1', 'on_extractimex2', 'on_extractemp2', + 'on_unfiltereddelta2', 'on_delta1', 'on_delta2', 'on_extratemp1', 'on_extratemp2', 'on_extratimex', 'on_extractimex1', 'on_extractemp1', 'on_extractimex2', 'on_extractemp2', 'BTprojection_tx', 'BTprojection_temp', 'ETprojection_tx', 'ETprojection_temp', 'DeltaBTprojection_tx', 'DeltaBTprojection_temp', 'DeltaETprojection_tx', 'DeltaETprojection_temp', 'timeindex', 'ETfunction', 'BTfunction', 'DeltaETfunction', 'DeltaBTfunction', 'safesaveflag', 'pid', 'background', 'backgroundprofile', 'backgroundprofile_moved_x', 'backgroundprofile_moved_y', 'backgroundDetails', 'backgroundeventsflag', 'backgroundpath', 'backgroundUUID', 'backgroundUUID', 'backgroundShowFullflag', 'backgroundKeyboardControlFlag', 'titleB', 'roastbatchnrB', 'roastbatchprefixB', 'roastbatchposB', 'temp1B', 'temp2B', 'temp1BX', 'temp2BX', 'timeB', 'abs_timeB', 'temp1Bdelta', 'temp2Bdelta', @@ -237,7 +237,7 @@ class tgraphcanvas(FigureCanvas): 'E1backgroundtimex', 'E2backgroundtimex', 'E3backgroundtimex', 'E4backgroundtimex', 'E1backgroundvalues', 'E2backgroundvalues', 'E3backgroundvalues', 'E4backgroundvalues', 'l_backgroundeventtype1dots', 'l_backgroundeventtype2dots', 'l_backgroundeventtype3dots', 'l_backgroundeventtype4dots', 'DeltaETBflag', 'DeltaBTBflag', 'clearBgbeforeprofileload', 'hideBgafterprofileload', 'heating_types', 'operator', 'organization', 'roastertype', 'roastersize', 'roasterheating', 'drumspeed', - 'organization_setup', 'operator_setup', 'roastertype_setup', 'roastersize_setup', 'roastersize_setup_default', 'roasterheating_setup', 'drumspeed_setup', 'last_batchsize', 'machinesetup_energy_ratings', + 'organization_setup', 'operator_setup', 'roastertype_setup', 'roastersize_setup', 'roastersize_setup_default', 'roasterheating_setup', 'roasterheating_setup_default', 'drumspeed_setup', 'last_batchsize', 'machinesetup_energy_ratings', 'machinesetup', 'roastingnotes', 'cuppingnotes', 'roastdate', 'roastepoch', 'roastepoch_timeout', 'lastroastepoch', 'batchcounter', 'batchsequence', 'batchprefix', 'neverUpdateBatchCounter', 'roastbatchnr', 'roastbatchprefix', 'roastbatchpos', 'roasttzoffset', 'roastUUID', 'plus_default_store', 'plus_store', 'plus_store_label', 'plus_coffee', 'plus_coffee_label', 'plus_blend_spec', 'plus_blend_spec_labels', 'plus_blend_label', 'plus_custom_blend', 'plus_sync_record_hash', 'plus_file_last_modified', 'beans', 'ETprojectFlag', 'BTprojectFlag', 'curveVisibilityCache', 'ETcurve', 'BTcurve', @@ -281,7 +281,7 @@ class tgraphcanvas(FigureCanvas): 'l_stat1', 'l_stat2', 'l_stat3', 'l_div1', 'l_div2', 'l_div3', 'l_div4', 'filterDropOut_replaceRoR_period', 'filterDropOut_spikeRoR_period', 'filterDropOut_tmin_C_default', 'filterDropOut_tmax_C_default', 'filterDropOut_tmin_F_default', 'filterDropOut_tmax_F_default', 'filterDropOut_spikeRoR_dRoR_limit_C_default', 'filterDropOut_spikeRoR_dRoR_limit_F_default', - 'filterDropOuts', 'filterDropOut_tmin', 'filterDropOut_tmax', 'filterDropOut_spikeRoR_dRoR_limit', 'minmaxLimits', + 'filterDropOuts', 'filterDropOut_tmin', 'filterDropOut_tmax', 'filterDropOut_spikeRoR_dRoR_limit', 'minmaxLimits', 'median_filter_factor_RoR', 'dropSpikes', 'dropDuplicates', 'dropDuplicatesLimit', 'median_filter_factor', 'liveMedianETRoRfilter', 'liveMedianBTRoRfilter', 'liveMedianETfilter', 'liveMedianBTfilter', 'interpolatemax', 'swapETBT', 'wheelflag', 'wheelnames', 'segmentlengths', 'segmentsalpha', 'wheellabelparent', 'wheelcolor', 'wradii', 'startangle', 'projection', 'wheeltextsize', 'wheelcolorpattern', 'wheeledge', @@ -3102,15 +3102,6 @@ def event_popup_action(self, action:QAction) -> None: pass if not self.flagstart: self.aw.autoAdjustAxis(deltas=False) -# elif firstDROP: # not needed as DROP cannot be occur in popup -# self.aw.buttonDROP.setFlat(True) -# self.aw.buttonCHARGE.setFlat(True) -# self.aw.buttonCHARGE.stopAnimation() -# self.aw.buttonDRY.setFlat(True) -# self.aw.buttonFCs.setFlat(True) -# self.aw.buttonFCe.setFlat(True) -# self.aw.buttonSCs.setFlat(True) -# self.aw.buttonSCe.setFlat(True) # update phases @@ -3126,10 +3117,10 @@ def event_popup_action(self, action:QAction) -> None: from artisanlib.events import customEventDlg dlg = customEventDlg(self.aw, self.aw, action.key[1]) # type: ignore[attr-defined] # "QAction" has no attribute "key" if dlg.exec(): - self.specialevents.append(action.key[1]) # type: ignore[attr-defined] # "QAction" has no attribute "key" # absolute time index - self.specialeventstype.append(dlg.type) # default: "--" - self.specialeventsStrings.append(dlg.description) - self.specialeventsvalue.append(dlg.value) + self.addEvent(action.key[1], # type: ignore[attr-defined] # "QAction" has no attribute "key" # absolute time index + dlg.type, # default: "--" + dlg.description, + dlg.value) self.aw.orderEvents() self.fileDirtySignal.emit() self.redraw(recomputeAllDeltas=(action.key[0] in {0, 6})) # type: ignore[attr-defined] # "QAction" has no attribute "key" # on moving CHARGE or DROP, we have to recompute the Deltas @@ -6336,7 +6327,7 @@ def clearMeasurements(self, andLCDs:bool=True) -> None: self.extractimex1[i],self.extractimex2[i],self.extractemp1[i],self.extractemp2[i] = [],[],[],[] self.replayedBackgroundEvents=[] self.beepedBackgroundEvents=[] - self.deleteEvents() # clear special events + self.clearEvents() # clear special events self.aw.lcd1.display('00:00') if self.aw.WebLCDs: self.updateWebLCDs(time='00:00') @@ -13369,10 +13360,7 @@ def EventRecordAction(self,extraevent:Optional[int] = None, eventtype:Optional[i fontprop_small = self.aw.mpl_fontproperties.copy() fontsize = 'xx-small' fontprop_small.set_size(fontsize) - self.specialevents.append(i) - self.specialeventstype.append(4) - self.specialeventsStrings.append(str(Nevents+1)) - self.specialeventsvalue.append(0) + self.addEvent(i,4,str(Nevents+1),0) #if event was initiated by an Extra Event Button then change the type,value, and string if extraevent is not None and eventtype is not None and eventvalue is not None: self.specialeventstype[-1] = eventtype @@ -13585,10 +13573,7 @@ def DeviceEventRecord(self,command): #index number i = len(self.timex)-1 if i > 0: - self.specialevents.append(i) # store absolute time index - self.specialeventstype.append(0) # set type (to the first index 0) - self.specialeventsStrings.append(command) # store the command in the string section of events (not a binary string) - self.specialeventsvalue.append(0) # empty + self.addEvent(i,0,command,0) temp_str = str(self.temp2[i]) if self.timeindex[0] != -1: start = self.timex[self.timeindex[0]] @@ -16055,11 +16040,12 @@ def convert_designer(self): #check and restore carried over events if self.eventtimecopy: - for etc in self.eventtimecopy: - self.specialevents.append(self.time2index(etc + self.timex[self.timeindex[0]])) - self.specialeventsStrings = self.specialeventsStringscopy[:] - self.specialeventsvalue = self.specialeventsvaluecopy[:] - self.specialeventstype = self.specialeventstypecopy[:] + self.clearEvents() # first clear previous special event lists + for i, etc in enumerate(self.eventtimecopy): + self.addEvent(self.time2index(etc + self.timex[self.timeindex[0]]), + self.specialeventstypecopy[i], + self.specialeventsStringscopy[i], + self.specialeventsvaluecopy[i]) #check for extra devices num = len(self.timex) @@ -16139,7 +16125,7 @@ def reset_designer(self,_=False): #saves next BT rate of change till next landmark as an event (example idea for arduino TC4) def designer_create_BT_rateofchange(self): - self.deleteEvents() + self.clearEvents() lastindexused = 0 for i in range(1,len(self.timeindex)): if self.timeindex[i]: @@ -16147,15 +16133,12 @@ def designer_create_BT_rateofchange(self): difftime = (self.timex[self.timeindex[i]] - self.timex[self.timeindex[lastindexused]])/60. if difftime: string = QApplication.translate('Label', 'BT {0} {1}/min for {2}').format(f'{difftemp/difftime:.1f}',self.mode,stringfromseconds(self.timex[self.timeindex[i]]-self.timex[self.timeindex[lastindexused]])) # pylint: disable=consider-using-f-string - self.specialevents.append(self.timeindex[lastindexused]) - self.specialeventstype.append(0) - self.specialeventsStrings.append(string) - self.specialeventsvalue.append(0) + self.addEvent(self.timeindex[lastindexused],0,string,0) lastindexused = i #saves next BT rate of change till next landmark as an event (example idea for arduino TC4) def designer_create_ET_rateofchange(self): - self.deleteEvents() + self.clearEvents() lastindexused = 0 for i in range(1,len(self.timeindex)): if self.timeindex[i]: @@ -16163,18 +16146,44 @@ def designer_create_ET_rateofchange(self): difftime = (self.timex[self.timeindex[i]] - self.timex[self.timeindex[lastindexused]])/60. if difftime: string = QApplication.translate('Label', 'ET {0} {1}/min for {2}').format(f'{difftemp/difftime:.1f}',self.mode,stringfromseconds(self.timex[self.timeindex[i]]-self.timex[self.timeindex[lastindexused]])) # pylint: disable=consider-using-f-string - self.specialevents.append(self.timeindex[lastindexused]) - self.specialeventstype.append(0) - self.specialeventsStrings.append(string) - self.specialeventsvalue.append(0) + self.addEvent(self.timeindex[lastindexused],0,string,0) lastindexused = i - def deleteEvents(self): +## Special Event API + + def clearEvents(self): self.specialevents = [] self.specialeventstype = [] self.specialeventsStrings = [] self.specialeventsvalue = [] + def addEvent(self, event_time_idx:int, event_type:int, event_description:str, event_value:float) -> None: + self.specialevents.append(event_time_idx) + self.specialeventstype.append(event_type) + self.specialeventsStrings.append(event_description) + self.specialeventsvalue.append(event_value) + + def setEvent(self, idx:int, event_time_idx:int, event_type:int, event_description:str, event_value:float) -> None: + if -1 < idx < len(self.specialevents): + self.specialevents[idx] = event_time_idx + self.specialeventstype[idx] = event_type + self.specialeventsStrings[idx] = event_description + self.specialeventsvalue[idx] = event_value + + def popEvent(self, idx:int = -1) -> None: + if len(self.specialevents) > (abs(idx)-1 if idx < 0 else idx): + self.specialevents.pop(idx) + self.specialeventstype.pop(idx) + self.specialeventsStrings.pop(idx) + self.specialeventsvalue.pop(idx) + + # delete the events at the given positions + def deleteEvents(self, positions:List[int]) -> None: + for idx in sorted(positions, reverse=True): + self.popEvent(idx) + +## + #this is used to create a string in pid language to reproduce the profile from Designer #NOTE: pid runs ET (temp1) def designer_create_ramp_command(self): @@ -16203,10 +16212,7 @@ def designer_create_ramp_command(self): self.clean_old_pid_commands() #do only one event but with all segments - self.specialevents.append(0) - self.specialeventstype.append(0) - self.specialeventsStrings.append(command) - self.specialeventsvalue.append(0) + self.addEvent(0,0,command,0) #this is used to create a string in ET temp language to reproduce the profile from Designer def designer_create_sv_command(self): @@ -16214,22 +16220,20 @@ def designer_create_sv_command(self): for i in range(len(self.timeindex)-1): command = 'SETSV::{self.temp1[self.timeindex[i+1]]:.1f}' if i > 0 and self.timeindex[i]: - self.specialevents.append(self.timeindex[i]) - self.specialeventstype.append(0) - self.specialeventsStrings.append(command) - self.specialeventsvalue.append(0) + self.addEvent( + self.timeindex[i], + 0, + command, + 0) #verifies there are no previous machine commands on events def clean_old_pid_commands(self): #check for possible preloaded machine commands target = 0 if self.specialevents: - for i in range(len(self.specialevents)): + for i in reversed(range(len(self.specialevents))): if '::' in self.specialeventsStrings[i]: - self.specialevents.pop(i) - self.specialeventstype.pop(i) - self.specialeventsStrings.pop(i) - self.specialeventsvalue.pop(i) + self.popEvent(i) target = 1 break #break or the index i can become larger than the new shorted length of specialevents if target: diff --git a/src/artisanlib/events.py b/src/artisanlib/events.py index a5d54dc35..be08dfb35 100644 --- a/src/artisanlib/events.py +++ b/src/artisanlib/events.py @@ -1745,10 +1745,11 @@ def applyQuantifiers(self,_): ld = d lt = t # add to event table - self.aw.qmc.specialevents.append(self.aw.qmc.time2index(timex[ii])) - self.aw.qmc.specialeventstype.append(i) - self.aw.qmc.specialeventsStrings.append('Q'+ self.aw.qmc.eventsvalues(float(d+1))) - self.aw.qmc.specialeventsvalue.append(float(d+1)) + self.aw.qmc.addEvent( + self.aw.qmc.time2index(timex[ii]), + i, + 'Q'+ self.aw.qmc.eventsvalues(float(d+1)), + float(d+1)) self.aw.qmc.fileDirty() redraw = True if self.aw.clusterEventsFlag: diff --git a/src/artisanlib/main.py b/src/artisanlib/main.py index ab2bccdde..b34e148fd 100644 --- a/src/artisanlib/main.py +++ b/src/artisanlib/main.py @@ -5968,10 +5968,11 @@ def orderEvents(self, lock=True): packed_events.sort(key=lambda tup: tup[0]) # unpack for i in range(nevents): - self.qmc.specialevents[i] = packed_events[i][0] - self.qmc.specialeventstype[i] = packed_events[i][1] - self.qmc.specialeventsStrings[i] = packed_events[i][2] - self.qmc.specialeventsvalue[i] = packed_events[i][3] + self.qmc.setEvent(i, + packed_events[i][0], + packed_events[i][1], + packed_events[i][2], + packed_events[i][3]) # we have to clear the event flag positions as those are now out of order self.qmc.l_event_flags_dict = {} self.qmc.l_event_flags_pos_dict = {} @@ -6028,20 +6029,7 @@ def clusterEventsType(self,tp): if self.qmc.specialeventstype[i] == tp: last_event_idx = i # remove marked events - specialevents = [] - specialeventstype = [] - specialeventsStrings = [] - specialeventsvalue = [] - for i, se in enumerate(self.qmc.specialevents): - if i not in indexes_to_be_removed: - specialevents.append(se) - specialeventstype.append(self.qmc.specialeventstype[i]) - specialeventsStrings.append(self.qmc.specialeventsStrings[i]) - specialeventsvalue.append(self.qmc.specialeventsvalue[i]) - self.qmc.specialevents = specialevents - self.qmc.specialeventstype = specialeventstype - self.qmc.specialeventsStrings = specialeventsStrings - self.qmc.specialeventsvalue = specialeventsvalue + self.qmc.deleteEvents(indexes_to_be_removed) finally: if self.qmc.profileDataSemaphore.available() < 1: self.qmc.profileDataSemaphore.release(1) @@ -11772,15 +11760,15 @@ def changeEventNumber(self,_=0): def miniEventRecord(self,_): lenevents = self.eNumberSpinBox.value() if lenevents: - self.qmc.specialeventstype[lenevents-1] = self.etypeComboBox.currentIndex() - self.qmc.specialeventsvalue[lenevents-1] = self.qmc.str2eventsvalue(str(self.valueEdit.text())) - self.qmc.specialeventsStrings[lenevents-1] = self.lineEvent.text() if self.qmc.timeindex[0] > -1: newtime = self.qmc.time2index(self.qmc.timex[self.qmc.timeindex[0]]+ stringtoseconds(str(self.etimeline.text()))) else: newtime = self.qmc.time2index(stringtoseconds(str(self.etimeline.text()))) - self.qmc.specialevents[lenevents-1] = newtime - + self.qmc.setEvent(lenevents-1, + newtime, + self.etypeComboBox.currentIndex(), + self.lineEvent.text(), + self.qmc.str2eventsvalue(self.valueEdit.text())) self.lineEvent.clearFocus() self.eNumberSpinBox.clearFocus() self.etimeline.clearFocus() @@ -14775,7 +14763,7 @@ def ndec(num): ndec_arr = numpy.array([ndec(x) for x in bt]) avgDecimal = numpy.average(ndec_arr) maxDecimal = numpy.amax(ndec_arr) - + # Calculate the resolution from the BT values # Sort the numbers in ascending order #dave # Calculate the differences between successive numbers #dave @@ -14785,7 +14773,7 @@ def ndec(num): resolution = numpy.min(numpy.diff(numpy.sort(bt))[numpy.nonzero(numpy.diff(numpy.sort(bt)))]) except Exception: # pylint: disable=broad-except #dave resolution = float('nan') #dave - + str_modeChanged = '' if profileMode in {'C', 'F'} and self.qmc.mode != profileMode: str_modeChanged = '*Result not reliable, the temperature mode was changed' @@ -21637,7 +21625,7 @@ def checkTop(self, d, offset, p0, p1, p2, p3, p4, p5, twice=False): d = d * f_dtwice # improved variant requesting for a certain minimum delta between the reading of interest and the next two post event legs: - return bool(d3 < d and d4 < d and ((abs(dpost) > min(maxdpre, offset + (f * abs(dpre)))) + return bool(d3 < d and d4 < d and ((abs(dpost) > min(maxdpre, offset + (f * abs(dpre)))) or (dpost < 0 and dpre < 0 and (-dpre - dpost) > dpre_dpost_diff))) # returns True if a BT break at i-2 is detected @@ -21647,15 +21635,15 @@ def checkTop(self, d, offset, p0, p1, p2, p3, p4, p5, twice=False): # . average delta after i-2 is negative and twice as high (absolute) as the one before # d is minimum temperature delta of the two legs after the event to prevent too early recognition based on noise def BTbreak(self,i,event): - if event in ['DROP','drop']: + if event in ('DROP','drop'): offset = self.qmc.btbreak_params['offset_drop'] d = self.qmc.btbreak_params['d_drop'] else: #CHARGE offset = self.qmc.btbreak_params['offset_charge'] d = self.qmc.btbreak_params['d_charge'] - + #dave -- must revisit the i>5 term!!! - if len(self.qmc.timex)>5 and i>4 and i < len(self.qmc.timex): #'i>4' prevents reading temp2[-1] or worse when using BTbreak post recording + if len(self.qmc.timex)>5 and 4 < i < len(self.qmc.timex): #'i>4' prevents reading temp2[-1] or worse when using BTbreak post recording if self.checkTop(d,offset,self.qmc.temp2[i-5],self.qmc.temp2[i-4],self.qmc.temp2[i-3],self.qmc.temp2[i-2],self.qmc.temp2[i-1],self.qmc.temp2[i]): return self.qmc.btbreak_params['tight'] if len(self.qmc.timex)>10 and i>10 and self.checkTop(d,offset,self.qmc.temp2[i-10],self.qmc.temp2[i-8],self.qmc.temp2[i-6],self.qmc.temp2[i-4],self.qmc.temp2[i-2],self.qmc.temp2[i],twice=True): @@ -23380,16 +23368,17 @@ def importPilot(self,_=False): # pyright: ignore [reportGeneralTypeIssues] # Cod time_str = time_entry.text if time_str is not None: time = float(stringtoseconds(time_str)) - self.qmc.specialevents.append(self.qmc.time2index(time)) - self.qmc.specialeventstype.append(3) burner_entry = elem.find('burnercapacity') if burner_entry is None: burner_entry = elem.find('nburnercapacity') if burner_entry is not None: burner = burner_entry.text if burner is not None: - self.qmc.specialeventsvalue.append(self.qmc.str2eventsvalue(burner)) - self.qmc.specialeventsStrings.append('') + self.qmc.addEvent( + self.qmc.time2index(time), + 3, + '', + self.qmc.str2eventsvalue(burner)) self.autoAdjustAxis() diff --git a/src/artisanlib/roast_properties.py b/src/artisanlib/roast_properties.py index 18190b460..a2c5fc815 100644 --- a/src/artisanlib/roast_properties.py +++ b/src/artisanlib/roast_properties.py @@ -4185,19 +4185,22 @@ def saveEventTable(self): try: timez = self.eventtable.cellWidget(i,0) assert isinstance(timez, QLineEdit) + time_idx: int if self.aw.qmc.timeindex[0] > -1: - self.aw.qmc.specialevents[i] = self.aw.qmc.time2index(self.aw.qmc.timex[self.aw.qmc.timeindex[0]]+ stringtoseconds(str(timez.text()))) + time_idx = self.aw.qmc.time2index(self.aw.qmc.timex[self.aw.qmc.timeindex[0]]+ stringtoseconds(str(timez.text()))) else: - self.aw.qmc.specialevents[i] = self.aw.qmc.time2index(stringtoseconds(str(timez.text()))) + time_idx = self.aw.qmc.time2index(stringtoseconds(str(timez.text()))) description = self.eventtable.cellWidget(i,3) assert isinstance(description, QLineEdit) - self.aw.qmc.specialeventsStrings[i] = description.text() etype = self.eventtable.cellWidget(i,4) assert isinstance(etype, MyQComboBox) - self.aw.qmc.specialeventstype[i] = etype.currentIndex() evalue = self.eventtable.cellWidget(i,5) assert isinstance(evalue, QLineEdit) - self.aw.qmc.specialeventsvalue[i] = self.aw.qmc.str2eventsvalue(str(evalue.text())) + self.aw.qmc.setEvent(i, + time_idx, + etype.currentIndex(), + description.text(), + self.aw.qmc.str2eventsvalue(evalue.text())) except Exception: # pylint: disable=broad-except pass except Exception as e: # pylint: disable=broad-except @@ -4319,10 +4322,7 @@ def clearEvents(self,_=False): self.aw.qmc.profileDataSemaphore.acquire(1) nevents = len(self.aw.qmc.specialevents) if nevents: - self.aw.qmc.specialevents = [] - self.aw.qmc.specialeventstype = [] - self.aw.qmc.specialeventsStrings = [] - self.aw.qmc.specialeventsvalue = [] + self.aw.qmc.clearEvents() except Exception as e: # pylint: disable=broad-except _log.exception(e) finally: @@ -4373,10 +4373,11 @@ def orderEventTableLoop(self): def addEventTable(self,_=False): if len(self.aw.qmc.timex): self.saveEventTable() - self.aw.qmc.specialevents.append(len(self.aw.qmc.timex)-1) #qmc.specialevents holds indexes in qmx.timex. Initialize event index - self.aw.qmc.specialeventstype.append(0) - self.aw.qmc.specialeventsStrings.append(str(len(self.aw.qmc.specialevents))) - self.aw.qmc.specialeventsvalue.append(0) + self.aw.qmc.addEvent( + len(self.aw.qmc.timex)-1, #qmc.specialevents holds indexes in qmx.timex. Initialize event index + 0, + str(len(self.aw.qmc.specialevents)), + 0) self.createEventTable(force=True) self.aw.qmc.redraw(recomputeAllDeltas=False) message = QApplication.translate('Message','Event #{0} added').format(str(len(self.aw.qmc.specialevents))) @@ -4385,22 +4386,6 @@ def addEventTable(self,_=False): message = QApplication.translate('Message','No profile found') self.aw.sendmessage(message) - def deleteEventRows(self,rows): - specialevents = [] - specialeventstype = [] - specialeventsStrings = [] - specialeventsvalue = [] - for r, se in enumerate(self.aw.qmc.specialevents): - if r not in rows: - specialevents.append(se) - specialeventstype.append(self.aw.qmc.specialeventstype[r]) - specialeventsStrings.append(self.aw.qmc.specialeventsStrings[r]) - specialeventsvalue.append(self.aw.qmc.specialeventsvalue[r]) - self.aw.qmc.specialevents = specialevents - self.aw.qmc.specialeventstype = specialeventstype - self.aw.qmc.specialeventsStrings = specialeventsStrings - self.aw.qmc.specialeventsvalue = specialeventsvalue - @pyqtSlot(bool) def deleteEventTable(self,_=False): if len(self.aw.qmc.specialevents): @@ -4411,15 +4396,11 @@ def deleteEventTable(self,_=False): rows = [] for s in selected: top = s.topRow() - for x in range(s.rowCount()): - rows.append(top + x) - self.deleteEventRows(rows) + rows.extend(list(range(top,top+s.rowCount()))) + self.aw.qmc.deleteEvents(rows) message = QApplication.translate('Message',' Events #{0} deleted').format(str([r+1 for r in rows])) else: - self.aw.qmc.specialevents.pop() - self.aw.qmc.specialeventstype.pop() - self.aw.qmc.specialeventsStrings.pop() - self.aw.qmc.specialeventsvalue.pop() + self.aw.qmc.popEvent() message = QApplication.translate('Message',' Event #{0} deleted').format(str(len(self.aw.qmc.specialevents)+1)) self.aw.qmc.fileDirty() self.createEventTable(force=True)