Skip to content

Commit e649827

Browse files
committed
- adds support for Dutch Master Roasters
- improved machine support for Schuilenburg PLCs - adds CHARGE_time to ComputedProfileInformation and eventsliderunits to ProfileInformation - refactors smoothing and RoR computation from Canvas to util - fixes issues on loading (partial) background profiles - improves NonTempDevice structure to support inhomogeneous settings - prevent and supress numpy polyfit warnings in software PID - adds roast message payload generator - lib updates
1 parent 1ba8fda commit e649827

23 files changed

Lines changed: 2511 additions & 670 deletions

src/artisanlib/atypes.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,33 @@
2626
from plus.stock import BlendList, Blend
2727

2828
class ComputedProfileInformation(TypedDict, total=False):
29+
CHARGE_time: float # time in seconds since start of recording (roastdate/roastepoch)
2930
CHARGE_ET: float
3031
CHARGE_BT: float
3132
TP_idx: int
32-
TP_time: float
33+
TP_time: float # time in seconds since CHARGE
3334
TP_ET: float
3435
TP_BT: float
3536
MET: float
36-
DRY_time: float
37+
DRY_time: float # time in seconds since CHARGE
3738
DRY_ET: float
3839
DRY_BT: float
39-
FCs_time: float
40+
FCs_time: float # time in seconds since CHARGE
4041
FCs_ET: float
4142
FCs_BT: float
42-
FCe_time: float
43+
FCe_time: float # time in seconds since CHARGE
4344
FCe_ET: float
4445
FCe_BT: float
45-
SCs_time: float
46+
SCs_time: float # time in seconds since CHARGE
4647
SCs_ET: float
4748
SCs_BT: float
48-
SCe_time: float
49+
SCe_time: float # time in seconds since CHARGE
4950
SCe_ET: float
5051
SCe_BT: float
51-
DROP_time: float
52+
DROP_time: float # time in seconds since CHARGE
5253
DROP_ET: float
5354
DROP_BT: float
54-
COOL_time: float
55+
COOL_time: float # time in seconds since CHARGE
5556
COOL_ET: float
5657
COOL_BT: float
5758
totaltime: float
@@ -203,6 +204,7 @@ class ProfileData(TypedDict, total=False):
203204
default_etypes: list[bool]
204205
default_etypes_set: list[int]
205206
etypes: list[str]
207+
eventsliderunits: list[str]
206208
cuppingnotes: str
207209
roastingnotes: str
208210
timex: list[float]
@@ -364,6 +366,7 @@ class ExtraDeviceSettings(TypedDict):
364366
extramarkersizes2 : list[float]
365367
default_etypes_set : list[int]
366368
etypes : list[str]
369+
eventsliderunits : list[str]
367370

368371
Palette = tuple[
369372
list[int], # 0: event button types

src/artisanlib/canvas.py

Lines changed: 154 additions & 417 deletions
Large diffs are not rendered by default.

src/artisanlib/colors.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ def setbgColorSlot(self, _:bool) -> None:
824824
# background colors
825825
def setbgColor(self, title:str, var:QPushButton, color:str) -> None:
826826
labelcolor = QColor(rgba_colorname2argb_colorname(color))
827-
colorf = self.aw.colordialog(labelcolor, alphasupport=True, parent=self)
827+
colorf = self.aw.colordialog(labelcolor, alphasupport=True)
828828
if colorf.isValid():
829829
color = argb_colorname2rgba_colorname(colorf.name(QColor.NameFormat.HexArgb))
830830
tc = self.aw.labelBorW(color)
@@ -847,7 +847,7 @@ def setbgColor(self, title:str, var:QPushButton, color:str) -> None:
847847
self.aw.sendmessage(QApplication.translate('Message','Color of {0} set to {1}').format(title,str(color)))
848848

849849
def setlcdColor(self, palette:dict[str,str], disj_palette:dict[str,str], select:str) -> None:
850-
res = self.aw.colordialog(QColor(rgba_colorname2argb_colorname(palette[select])), alphasupport=True, parent=self)
850+
res = self.aw.colordialog(QColor(rgba_colorname2argb_colorname(palette[select])), alphasupport=True)
851851
if QColor.isValid(res):
852852
nc = argb_colorname2rgba_colorname(res.name(QColor.NameFormat.HexArgb))
853853
if nc == disj_palette[select] or (nc in {'white', '#ffffff', '#fffffffff'} and disj_palette[select] in {'white', '#ffffff', '#fffffffff'}) or (nc in {'black', '#000000', '#000000ff'} and disj_palette[select] in {'black', '#000000', '#000000ff'}):
@@ -934,7 +934,7 @@ def colorButton(self, s:str) -> QPushButton:
934934
# foreground colors
935935
def setColor(self, title:str, var:QPushButton, color:str) -> None:
936936
labelcolor = QColor(rgba_colorname2argb_colorname(self.aw.qmc.palette[color]))
937-
colorf = self.aw.colordialog(labelcolor, alphasupport=True, parent=self)
937+
colorf = self.aw.colordialog(labelcolor, alphasupport=True)
938938
if colorf.isValid():
939939
self.aw.qmc.palette[color] = argb_colorname2rgba_colorname(colorf.name(QColor.NameFormat.HexArgb))
940940
self.aw.updateCanvasColors()

src/artisanlib/comparator.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@
2929
from artisanlib.main import ApplicationWindow # noqa: F401 # pylint: disable=unused-import
3030
from artisanlib.atypes import ProfileData # pylint: disable=unused-import
3131
from matplotlib.lines import Line2D # type:ignore[untyped-import,unused-ignore] # pylint: disable=unused-import
32-
from matplotlib.backend_bases import PickEvent # type:ignore[untyped-import,unused-ignore] # pylint: disable=unused-import
32+
from matplotlib.backend_bases import PickEvent, Event # type:ignore[untyped-import,unused-ignore] # pylint: disable=unused-import
3333
from matplotlib.legend import Legend # type:ignore[untyped-import,unused-ignore] # pylint: disable=unused-import
3434
from PyQt6.QtWidgets import QLayoutItem, QLayout, QScrollBar # pylint: disable=unused-import
3535
from PyQt6.QtGui import QStandardItem, QKeyEvent, QDropEvent, QDragEnterEvent, QCloseEvent # pylint: disable=unused-import
3636
from PyQt6.QtCore import QMimeData # pylint: disable=unused-import
3737

3838
from artisanlib.util import (deltaLabelUTF8, decodeLocal, decodeLocalStrict, stringfromseconds, fromFtoCstrict,
39-
fromCtoFstrict, fill_gaps, float2float, deserialize, float2str)
39+
fromCtoFstrict, fill_gaps, float2float, deserialize, float2str, smooth_list)
4040
from artisanlib.suppress_errors import suppress_stdout_stderr
4141
from artisanlib.dialogs import ArtisanDialog
4242
from artisanlib.widgets import MyQComboBox
@@ -364,8 +364,10 @@ def recompute(self) -> None:
364364
timex_lin = numpy.linspace(self.timex[0],self.timex[-1],len(self.timex))
365365
else:
366366
timex_lin = None
367-
self.stemp1 = list(self.aw.qmc.smooth_list(self.timex,self.temp1,window_len=self.aw.qmc.curvefilter,decay_smoothing=decay_smoothing_p,a_lin=timex_lin))
368-
self.stemp2 = list(self.aw.qmc.smooth_list(self.timex,self.temp2,window_len=self.aw.qmc.curvefilter,decay_smoothing=decay_smoothing_p,a_lin=timex_lin))
367+
self.stemp1 = list(smooth_list(self.timex,self.temp1,window_len=self.aw.qmc.curvefilter,decay_smoothing=decay_smoothing_p,a_lin=timex_lin,
368+
medfilt_factor=self.aw.qmc.median_filter_factor, filter_dropouts=self.aw.qmc.filterDropOuts))
369+
self.stemp2 = list(smooth_list(self.timex,self.temp2,window_len=self.aw.qmc.curvefilter,decay_smoothing=decay_smoothing_p,a_lin=timex_lin,
370+
medfilt_factor=self.aw.qmc.median_filter_factor, filter_dropouts=self.aw.qmc.filterDropOuts))
369371
# we resample the temperatures of extra device curves to regular interval timestamps
370372
self.extrastemp1 = []
371373
self.extrastemp2 = []
@@ -374,12 +376,16 @@ def recompute(self) -> None:
374376
timex_lin = numpy.linspace(timex[0],timex[-1],len(timex))
375377
else:
376378
timex_lin = None
377-
self.extrastemp1.append(list(self.aw.qmc.smooth_list(timex,self.extratemp1[i],window_len=self.aw.qmc.curvefilter,decay_smoothing=decay_smoothing_p,a_lin=timex_lin)))
378-
self.extrastemp2.append(list(self.aw.qmc.smooth_list(timex,self.extratemp2[i],window_len=self.aw.qmc.curvefilter,decay_smoothing=decay_smoothing_p,a_lin=timex_lin)))
379+
self.extrastemp1.append(list(smooth_list(timex,self.extratemp1[i],window_len=self.aw.qmc.curvefilter,decay_smoothing=decay_smoothing_p,a_lin=timex_lin,
380+
medfilt_factor=self.aw.qmc.median_filter_factor, filter_dropouts=self.aw.qmc.filterDropOuts)))
381+
self.extrastemp2.append(list(smooth_list(timex,self.extratemp2[i],window_len=self.aw.qmc.curvefilter,decay_smoothing=decay_smoothing_p,a_lin=timex_lin,
382+
medfilt_factor=self.aw.qmc.median_filter_factor, filter_dropouts=self.aw.qmc.filterDropOuts)))
379383
# recompute deltas
380384
cf = self.aw.qmc.curvefilter*2 # we smooth twice as heavy for PID/RoR calculation as for normal curve smoothing
381-
t1 = self.aw.qmc.smooth_list(self.timex,self.temp1,window_len=cf,decay_smoothing=decay_smoothing_p,a_lin=timex_lin)
382-
t2 = self.aw.qmc.smooth_list(self.timex,self.temp2,window_len=cf,decay_smoothing=decay_smoothing_p,a_lin=timex_lin)
385+
t1 = smooth_list(self.timex,self.temp1,window_len=cf,decay_smoothing=decay_smoothing_p,a_lin=timex_lin,
386+
medfilt_factor=self.aw.qmc.median_filter_factor, filter_dropouts=self.aw.qmc.filterDropOuts)
387+
t2 = smooth_list(self.timex,self.temp2,window_len=cf,decay_smoothing=decay_smoothing_p,a_lin=timex_lin,
388+
medfilt_factor=self.aw.qmc.median_filter_factor, filter_dropouts=self.aw.qmc.filterDropOuts)
383389
if self.timeindex[0]>-1:
384390
RoR_start = min(self.timeindex[0]+10, len(self.timex)-1)
385391
else:
@@ -1094,7 +1100,7 @@ def __init__(self, parent:QWidget, aw:'ApplicationWindow', foreground:str|None =
10941100
self.disableButtons()
10951101
self.aw.disableEditMenus(compare=True)
10961102

1097-
self.pick_handler_id = self.aw.qmc.fig.canvas.mpl_connect('pick_event', self.onpick_event)
1103+
self.pick_handler_id = self.aw.qmc.fig.canvas.mpl_connect('pick_event', cast('Callable[[Event],None]', self.onpick_event))
10981104

10991105
settings = QSettings()
11001106
if settings.contains('CompareGeometry'):

src/artisanlib/events.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,7 +2724,7 @@ def setcoloreventline3(self,_:bool = False) -> None:
27242724
self.setcoloreventline(3)
27252725

27262726
def setcoloreventline(self, b:int) -> None:
2727-
colorf = self.aw.colordialog(QColor(self.aw.qmc.EvalueColor[b]), parent=self)
2727+
colorf = self.aw.colordialog(QColor(self.aw.qmc.EvalueColor[b]))
27282728
if colorf.isValid():
27292729
colorname = str(colorf.name())
27302730
self.aw.qmc.EvalueColor[b] = colorname
@@ -2746,7 +2746,7 @@ def setcoloreventtext3(self,_:bool = False) -> None:
27462746
self.setcoloreventtext(3)
27472747

27482748
def setcoloreventtext(self, b:int) -> None:
2749-
colorf = self.aw.colordialog(QColor(self.aw.qmc.EvalueTextColor[b]), parent=self)
2749+
colorf = self.aw.colordialog(QColor(self.aw.qmc.EvalueTextColor[b]))
27502750
if colorf.isValid():
27512751
colorname = str(colorf.name())
27522752
self.aw.qmc.EvalueTextColor[b] = colorname
@@ -3152,7 +3152,7 @@ def setvisibilitytyeventbutton(self, _:int) -> None:
31523152
def setbuttoncolor(self, _:bool = False) -> None:
31533153
i = self.aw.findWidgetsRow(self.eventbuttontable,self.sender(),7)
31543154
if i is not None and i < len(self.extraeventbuttoncolor):
3155-
colorf = self.aw.colordialog(QColor(self.extraeventbuttoncolor[i]), parent=self)
3155+
colorf = self.aw.colordialog(QColor(self.extraeventbuttoncolor[i]))
31563156
if colorf.isValid():
31573157
self.extraeventbuttoncolor[i] = str(colorf.name())
31583158
textColor = self.extraeventbuttontextcolor[i]
@@ -3171,7 +3171,7 @@ def setbuttoncolor(self, _:bool = False) -> None:
31713171
def setbuttontextcolor(self, _:bool = False) -> None:
31723172
i = self.aw.findWidgetsRow(self.eventbuttontable,self.sender(),8)
31733173
if i is not None and i < len(self.extraeventbuttontextcolor):
3174-
colorf = self.aw.colordialog(QColor(self.extraeventbuttontextcolor[i]), parent=self)
3174+
colorf = self.aw.colordialog(QColor(self.extraeventbuttontextcolor[i]))
31753175
if colorf.isValid():
31763176
self.extraeventbuttontextcolor[i] = str(colorf.name())
31773177
textColor = self.extraeventbuttontextcolor[i]

0 commit comments

Comments
 (0)