Skip to content

Commit

Permalink
- makes background profile datatable more robust
Browse files Browse the repository at this point in the history
- indicates artisan.plus connection loss more reliable
- don't register incomplete roasts in scheduler
- makes loading of (broken) profiles more robust
- updates matplotlib and other libs
- prevents incomplete blends
- energy tab improvements
 . protocol tool never generates '_:_' entries
 . updates protocol duration validator regex to reset Default buttons on clearing entries
  . reorganization of signal processing to ensure complete reset to defaults
  • Loading branch information
MAKOMO committed Dec 2, 2024
1 parent b8766e9 commit 70c29fe
Show file tree
Hide file tree
Showing 74 changed files with 93,974 additions and 93,262 deletions.
Binary file modified doc/help_dialogs/Input_files/eventbuttons.xlsx
Binary file not shown.
12 changes: 6 additions & 6 deletions doc/help_dialogs/Output_html/eventbuttons_help.html
Original file line number Diff line number Diff line change
Expand Up @@ -539,18 +539,18 @@
</tr>
<tr>
<td>&#160;</td>
<td>outhub(&lt;channel&gt;,&lt;value&gt;[,&lt;sn&gt;])</td>
<td>PHIDGET HUB PWM Output: &lt;value&gt; in [0-100]</td>
<td>outhub(&lt;port&gt;,&lt;value&gt;[,&lt;sn&gt;])</td>
<td>PHIDGET HUB PWM Output ON port &lt;port&gt; to &lt;value&gt; in [0-100]</td>
</tr>
<tr>
<td>&#160;</td>
<td>togglehub(&lt;channel&gt;[,&lt;sn&gt;])</td>
<td>PHIDGET HUB PWM Output: toggles &lt;channel&gt;</td>
<td>togglehub(&lt;port&gt;[,&lt;sn&gt;])</td>
<td>PHIDGET HUB PWM Output: toggles &lt;port&gt;</td>
</tr>
<tr>
<td>&#160;</td>
<td>pulsehub(&lt;channel&gt;,&lt;millis&gt;[,&lt;sn&gt;])</td>
<td>PHIDGET HUB PWM Output: turn &lt;channel&gt; on for &lt;millis&gt; milliseconds</td>
<td>pulsehub(&lt;port&gt;,&lt;millis&gt;[,&lt;sn&gt;])</td>
<td>PHIDGET HUB PWM Output: turn &lt;port&gt; ON for &lt;millis&gt; milliseconds</td>
</tr>
<tr>
<td>&#160;</td>
Expand Down
2 changes: 1 addition & 1 deletion src/artisanlib/background.py
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ def createDataTable(self) -> None:
#### lock shared resources #####
self.aw.qmc.profileDataSemaphore.acquire(1)

ndata = len(self.aw.qmc.timeB)
ndata = min(len(self.aw.qmc.timeB), len(self.aw.qmc.temp1B), len(self.aw.qmc.temp2B))

self.datatable.clear() # this crashes Ubuntu 16.04
# if ndata != 0:
Expand Down
26 changes: 17 additions & 9 deletions src/artisanlib/canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -6894,9 +6894,6 @@ def reset(self,redraw:bool = True, soundOn:bool = True, keepProperties:bool = Fa
if self.crossmarker:
self.togglecrosslines()

if self.aw is not None:
self.aw.updatePlusStatus()

except Exception as ex: # pylint: disable=broad-except
_log.exception(ex)
_, _, exc_tb = sys.exc_info()
Expand Down Expand Up @@ -6934,6 +6931,9 @@ def reset(self,redraw:bool = True, soundOn:bool = True, keepProperties:bool = Fa

self.aw.qmc.timealign(redraw=False)

if self.aw is not None:
self.aw.updatePlusStatus()

### REDRAW ##
if redraw:
self.aw.autoAdjustAxis(background=not keepProperties) # if reset() triggered by ON, we ignore background on adjusting the axis and adjust according to RESET min/max
Expand Down Expand Up @@ -11937,15 +11937,17 @@ def startPhidgetManager(self) -> None:
if self.phidgetRemoteFlag:
try:
self.addPhidgetServer()
_log.info('phidgetServer started')
except Exception: # pylint: disable=broad-except
_log.info('phidgetServer added')
except Exception as e: # pylint: disable=broad-except
_log.exception(e)
if self.device in self.phidgetDevices:
self.adderror(QApplication.translate('Error Message',"Exception: PhidgetManager couldn't be started. Verify that the Phidget driver is correctly installed!"))
self.adderror(QApplication.translate('Error Message',"Exception: phidgetServer couldn't be added. Verify that the Phidget driver is correctly installed!"))
if self.phidgetManager is None:
try:
self.phidgetManager = PhidgetManager()
_log.info('phidgetManager started')
except Exception: # pylint: disable=broad-except
except Exception as e: # pylint: disable=broad-except
_log.exception(e)
if self.device in self.phidgetDevices:
self.adderror(QApplication.translate('Error Message',"Exception: PhidgetManager couldn't be started. Verify that the Phidget driver is correctly installed!"))

Expand Down Expand Up @@ -12325,6 +12327,8 @@ def OffMonitorCloseDown(self) -> None:
if self.flagKeepON and len(self.timex) > 10:
QTimer.singleShot(300, self.onMonitorSignal.emit)

self.aw.updatePlusStatusSignal.emit() # update plus icon (roast might not have been uploaded yet)

except Exception as ex: # pylint: disable=broad-except
_log.exception(ex)
_, _, exc_tb = sys.exc_info()
Expand Down Expand Up @@ -12799,11 +12803,15 @@ def OnRecorder(self) -> None:
def OffRecorder(self, autosave:bool = True, enableButton:bool = True) -> None:
_log.info('MODE: STOP RECORDING')
try:
# mark DROP if not yet set, at least 7min roast time and CHARGE is set and either autoDROP is active or DROP button is hidden
if self.timeindex[6] == 0 and self.timeindex[0] != -1 and (self.autoDropFlag or not self.buttonvisibility[6]):
# mark DROP if not yet set (and DROP not undone), at least 7min roast time and CHARGE is set and either autoDROP is active or DROP button is hidden
if self.timeindex[6] == 0 and self.timeindex[0] != -1 and self.autoDROPenabled and (self.autoDropFlag or not self.buttonvisibility[6]):
start = self.timex[self.timeindex[0]]
if (len(self.timex)>0 and self.timex[-1] - start) > 7*60: # only after 7min into the roast
self.markDrop()
if self.timeindex[6] == 0 and self.autoDROPenabled:
# if DROP is still not set (and was never set before, eg. autoDROP is still enabled), we reset the scheduleID not
# to have this still incomplete roast be associated with any scheduleItem (rule: a roast without a DROP is never automatically registered as scheduleItem)
self.scheduleID = None
self.cacheforBbp() # save items for bbp
self.aw.enableSaveActions()
self.aw.resetCurveVisibilities()
Expand Down
1 change: 1 addition & 0 deletions src/artisanlib/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,7 @@ def __init__(self, parent:QWidget, aw:'ApplicationWindow', activeTab:int = 0) ->
self.phidgetPassword.setEnabled(self.aw.qmc.phidgetServerID != '')
self.phidgetPassword.setMinimumWidth(100)
self.phidgetPassword.setEnabled(self.aw.qmc.phidgetRemoteFlag)
self.phidgetPassword.setToolTip(QApplication.translate('Tooltip','Phidget server password'))
phidgetPortLabel = QLabel(QApplication.translate('Label','Port'))
self.phidgetPort = QLineEdit(str(self.aw.qmc.phidgetPort))
self.phidgetPort.setMaximumWidth(70)
Expand Down
54 changes: 43 additions & 11 deletions src/artisanlib/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13000,8 +13000,32 @@ def loadbackground(self, filename:str) -> None:
tb = profile['timex']
t1 = profile['temp1']
t2 = profile['temp2']
# ensure that timex, temp1 and temp2 are all of the same (minimal-)length
data_len:int = min(len(tb), len(t1), len(t2))
tb = tb[:data_len]
t1 = t1[:data_len]
t2 = t2[:data_len]

timex = profile['extratimex']
t1x = profile['extratemp1']
t2x = profile['extratemp2']
# ensure that number of extra device data is consistent
number_extra_devices = min(len(timex), len(t1x), len(t2x))
timex = timex[:number_extra_devices]
t1x = t1x[:number_extra_devices]
t2x = t2x[:number_extra_devices]
# ensure that the extra device data is of length data_len
for c in range(number_extra_devices):
timex[c] = timex[c][:data_len]
t1x[c] = t1x[c][:data_len]
t2x[c] = t2x[c][:data_len]
if len(timex[c]) != data_len:
timex[c] = tb[:]
if len(t1x[c]) != data_len:
t1x[c] = [-1]*data_len
if len(t2x[c]) != data_len:
t2x[c] = [-1]*data_len


# reset the movebackground cache:
self.qmc.backgroundprofile_moved_x = 0
Expand Down Expand Up @@ -13033,7 +13057,6 @@ def loadbackground(self, filename:str) -> None:

names1x = [decodeLocalStrict(x) for x in profile['extraname1']]
names2x = [decodeLocalStrict(x) for x in profile['extraname2']]
timex = profile['extratimex']
self.qmc.temp1B,self.qmc.temp2B,self.qmc.timeB, self.qmc.temp1BX, self.qmc.temp2BX = t1,t2,tb,t1x,t2x
self.qmc.abs_timeB = tb.copy() #invariant copy of timeB
self.qmc.extratimexB = timex
Expand Down Expand Up @@ -13135,7 +13158,7 @@ def loadbackground(self, filename:str) -> None:
if 'etypes' in profile:
self.qmc.Betypes = self.get_profile_etypes(self.qmc.backgroundprofile)
if 'timeindex' in profile:
self.qmc.timeindexB = [max(0,v) if i>0 else max(-1,v) for i,v in enumerate(profile['timeindex'])] #if new profile found with variable timeindex
self.qmc.timeindexB = [max(0,min(v,data_len-1)) if i>0 else max(-1,min(v,data_len-1)) for i,v in enumerate(profile['timeindex'])] #if new profile found with variable timeindex
if self.qmc.phasesfromBackgroundflag:
# adjust phases by DryEnd and FCs events from background profile
if self.qmc.timeindexB[1] and len(self.qmc.timeindexB) > 1 and len(self.qmc.temp2B) > self.qmc.timeindexB[1]:
Expand Down Expand Up @@ -15118,16 +15141,27 @@ def setProfile(self, filename:Optional[str], profile:'ProfileData', quiet:bool =
self.qmc.cuppingnotes = decodeLocalStrict(profile['cuppingnotes'])
else:
self.qmc.cuppingnotes = ''

if 'timex' in profile:
self.qmc.timex = profile['timex']
if 'temp1' in profile:
self.qmc.temp1 = profile['temp1']
if 'temp2' in profile:
self.qmc.temp2 = profile['temp2']

# ensure that timex, temp1 and temp2 are all of the same (minimal-)length
data_len:int = min(len(self.qmc.timex), len(self.qmc.temp1), len(self.qmc.temp2))
self.qmc.timex = self.qmc.timex[:data_len]
self.qmc.temp1 = self.qmc.temp1[:data_len]
self.qmc.temp2 = self.qmc.temp2[:data_len]

# ensure that extra timex and temp lists are as long as the main timex
for i, _ in enumerate(self.qmc.extratimex):
if not isinstance(self.qmc.extratimex[i], list) or len(self.qmc.extratimex[i]) != len(self.qmc.timex):
self.qmc.extratimex[i] = self.qmc.timex
if not isinstance(self.qmc.extratemp1[i], list) or len(self.qmc.extratemp1[i]) != len(self.qmc.timex):
if not isinstance(self.qmc.extratimex[i], list) or len(self.qmc.extratimex[i]) != data_len:
self.qmc.extratimex[i] = self.qmc.timex[:]
if not isinstance(self.qmc.extratemp1[i], list) or len(self.qmc.extratemp1[i]) != data_len:
self.qmc.extratemp1[i] = [-1]*len(self.qmc.timex)
if not isinstance(self.qmc.extratemp2[i], list) or len(self.qmc.extratemp2[i]) != len(self.qmc.timex):
if not isinstance(self.qmc.extratemp2[i], list) or len(self.qmc.extratemp2[i]) != data_len:
self.qmc.extratemp2[i] = [-1]*len(self.qmc.timex)

# alarms
Expand All @@ -15138,10 +15172,6 @@ def setProfile(self, filename:Optional[str], profile:'ProfileData', quiet:bool =
self.qmc.extraNoneTempHint2 = profile.get('extraNoneTempHint2', [])

m = str(profile['mode']) if 'mode' in profile else self.qmc.mode
if 'temp1' in profile:
self.qmc.temp1 = profile['temp1']
if 'temp2' in profile:
self.qmc.temp2 = profile['temp2']
if 'ambientTemp' in profile:
self.qmc.ambientTemp = profile['ambientTemp']
self.qmc.greens_temp = profile.get('greens_temp', 0.0)
Expand Down Expand Up @@ -15264,7 +15294,9 @@ def setProfile(self, filename:Optional[str], profile:'ProfileData', quiet:bool =
self.loadBbpFromProfile(profile)

if 'timeindex' in profile:
self.qmc.timeindex = [max(0,v) if i>0 else max(-1,v) for i,v in enumerate(profile['timeindex'])]
# ensure that no timeindex points outside of timex
self.qmc.timeindex = [max(0,min(v,data_len-1)) if i>0 else max(-1,min(v,data_len-1)) for i,v in enumerate(profile['timeindex'])]

if self.qmc.locktimex:
if self.qmc.timeindex[0] != -1:
self.qmc.startofx = self.qmc.timex[self.qmc.timeindex[0]] + self.qmc.locktimex_start
Expand Down
Loading

0 comments on commit 70c29fe

Please sign in to comment.