Skip to content

Commit 061428a

Browse files
committed
minor adjustments in preparation of the v1.4 release
1 parent d26e3cf commit 061428a

33 files changed

+37645
-37249
lines changed

src/README.txt

+21-21
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
Artisan helps coffee roasters record, analyze, and control roast profiles. With the help of a thermocouple data logger, or a proportional–integral–derivative controller (PID controller), this software offers roasting metrics to help make decisions that influence the final coffee flavor.
2-
3-
Artisan is free for personal and commercial use, but asks for a donation <https://www.paypal.me/MarkoLuther>.
2+
3+
Artisan is free for personal and commercial use, but asks for a donation <https://www.paypal.me/MarkoLuther>.
44

55

66
HOME
7-
8-
<https://artisan-scope.org>
7+
8+
<https://artisan-scope.org>
99

1010
The home of its development is on GitHub were all source and binary files are available as well as an issue tracker.
1111

@@ -25,25 +25,25 @@ https://artisan-roasterscope.blogspot.de
2525

2626
FEATURES
2727

28-
Runs on 64bit Windows 8, Mac OS X 10.13, Redhat/Debian Linux (incl. Raspberry Pi) and supports a large number of devices and roasting machines. See <https://artisan-scope.org/devices/index> for supported Supported Devices and <https://artisan-scope.org/machines/index> for supported machines.
29-
30-
Artisan offers
31-
- unlimited number of curves
32-
- rate-of-rise (RoR), area-under-the-curve (AUC), development-time-ratio (DTR) calculations
33-
- projection lines and head-up-display (HUD)
34-
- roast profile evaluation and statistics
35-
- roast-, production- and ranking reports
36-
- automated reproduction of roasts via alarm programs, replay of events or PID control
37-
- batch counter
38-
- profile designer, cupping editor, spider- and wheel graph
39-
- user defined buttons and sliders with programable actions
40-
- many import and export formats
28+
Runs on 64bit Windows 8, Mac OS X 10.13 (legacy builds support 10.10), Redhat/Debian Linux (incl. Raspberry Pi) and supports a large number of devices and roasting machines. See <https://artisan-scope.org/devices/index> for supported Supported Devices and <https://artisan-scope.org/machines/index> for supported machines.
29+
30+
Artisan offers
31+
- unlimited number of curves
32+
- rate-of-rise (RoR), area-under-the-curve (AUC), development-time-ratio (DTR) calculations
33+
- projection lines and head-up-display (HUD)
34+
- roast profile evaluation and statistics
35+
- roast-, production- and ranking reports
36+
- automated reproduction of roasts via alarm programs, replay of events or PID control
37+
- batch counter
38+
- profile designer, cupping editor, spider- and wheel graph
39+
- user defined buttons and sliders with programable actions
40+
- many import and export formats
4141

4242

4343
INSTALLATION
4444

4545
See <https://github.com/artisan-roaster-scope/artisan/blob/master/wiki/Installation.md>
46-
46+
4747

4848

4949
LICENCE
@@ -83,13 +83,13 @@ Artisan uses the following libraries in unmodified forms:
8383
- pyinstaller under the GPL license
8484
http://www.pyinstaller.org
8585
- pymodbus under the BSD License by Galen Collins
86-
https://github.com/bashwork/pymodbus
87-
- python-snap7 under MIT license
86+
https://github.com/bashwork/pymodbus
87+
- python-snap7 under MIT license
8888
https://github.com/gijzelaerr/python-snap7
8989
- arabic_reshaper.py under GPL by Abd Allah Diab (Mpcabd)
9090

9191

9292

9393
VERSION HISTORY
94-
94+
9595
See <https://github.com/artisan-roaster-scope/artisan>

src/artisanlib/main.py

+84-41
Original file line numberDiff line numberDiff line change
@@ -11109,6 +11109,11 @@ def __init__(self, parent = None):
1110911109

1111011110
#FILE menu
1111111111
self.newRoastMenu = self.fileMenu.addMenu(UIconst.FILE_MENU_NEW)
11112+
# add NEW menu item
11113+
newRoastAction = QAction(UIconst.FILE_MENU_NEW,self)
11114+
newRoastAction.setShortcut(QKeySequence.New)
11115+
newRoastAction.triggered.connect(self.newRoast)
11116+
self.newRoastMenu.addAction(newRoastAction)
1111211117

1111311118
self.fileLoadAction = QAction(UIconst.FILE_MENU_OPEN,self)
1111411119
self.fileLoadAction.setShortcut(QKeySequence.Open)
@@ -12845,10 +12850,10 @@ def newRecentRoast(self):
1284512850
def updateNewMenuRecentRoasts(self):
1284612851
self.newRoastMenu.clear()
1284712852
# add NEW menu item
12848-
self.newRoastAction = QAction(UIconst.FILE_MENU_NEW,self)
12849-
self.newRoastAction.setShortcut(QKeySequence.New)
12850-
self.newRoastAction.triggered.connect(self.newRoast)
12851-
self.newRoastMenu.addAction(self.newRoastAction)
12853+
newRoastAction = QAction(UIconst.FILE_MENU_NEW,self)
12854+
newRoastAction.setShortcut(QKeySequence.New)
12855+
newRoastAction.triggered.connect(self.newRoast)
12856+
self.newRoastMenu.addAction(newRoastAction)
1285212857
# add recent roasts items
1285312858
if len(self.recentRoasts) > 0:
1285412859
self.newRoastMenu.addSeparator()
@@ -16254,12 +16259,12 @@ def newRoast(self):
1625416259
#########################################
1625516260
if self.qmc.flagstart:
1625616261
if self.qmc.timeindex[0] == -1:
16257-
self.sendmessage(QApplication.translate("Message","No profile found", None))
16262+
self.sendmessage(QApplication.translate("Message","NEW ROAST canceled: incomplete profile lacking CHARGE and DROP found", None))
1625816263
return
1625916264
#mark drop if not yet done
1626016265
if self.qmc.timeindex[6] == 0:
1626116266
# self.qmc.markDrop()
16262-
self.sendmessage(QApplication.translate("Message","No profile found", None))
16267+
self.sendmessage(QApplication.translate("Message","NEW ROAST canceled: incomplete profile lacking DROP found", None))
1626316268
return
1626416269
#invoke "OFF"
1626516270
self.qmc.OffMonitor()
@@ -17850,19 +17855,19 @@ def setProfile(self,filename,profile,quiet=False):
1785017855
else:
1785117856
self.qmc.title = QApplication.translate("Scope Title", "Roaster Scope",None)
1785217857

17853-
##PLUS (for now stored but not loaded)
17854-
## if "plus_store" in profile:
17855-
## self.qmc.plus_store = d(profile["plus_store"])
17856-
## else:
17857-
## self.qmc.plus_store = None
17858-
## if "plus_coffee" in profile:
17859-
## self.qmc.plus_coffee = d(profile["plus_coffee"])
17860-
## else:
17861-
## self.qmc.plus_coffee = None
17862-
## if "plus_blend" in profile:
17863-
## self.qmc.plus_blend = d(profile["plus_blend"])
17864-
## else:
17865-
## self.qmc.plus_blend = None
17858+
##PLUS
17859+
if "plus_store" in profile:
17860+
self.qmc.plus_store = d(profile["plus_store"])
17861+
else:
17862+
self.qmc.plus_store = None
17863+
if "plus_coffee" in profile:
17864+
self.qmc.plus_coffee = d(profile["plus_coffee"])
17865+
else:
17866+
self.qmc.plus_coffee = None
17867+
if "plus_blend" in profile:
17868+
self.qmc.plus_blend = d(profile["plus_blend"])
17869+
else:
17870+
self.qmc.plus_blend = None
1786617871

1786717872

1786817873
if "beans" in profile:
@@ -18462,6 +18467,7 @@ def getProfile(self):
1846218467
profile["volume"] = [self.qmc.volume[0],self.qmc.volume[1],encodeLocal(self.qmc.volume[2])]
1846318468
profile["density"] = [self.qmc.density[0],encodeLocal(self.qmc.density[1]),self.qmc.density[2],encodeLocal(self.qmc.density[3])]
1846418469
profile["roastertype"] = encodeLocal(self.qmc.roastertype)
18470+
profile["machinesetup"] = encodeLocal(self.qmc.machinesetup)
1846518471
profile["operator"] = encodeLocal(self.qmc.operator)
1846618472
profile["drumspeed"] = self.qmc.drumspeed
1846718473
profile["heavyFC"] = self.qmc.heavyFC_flag
@@ -18864,16 +18870,17 @@ def settingsLoad(self, filename=None):
1886418870

1886518871
if settings.contains("fullscreen"):
1886618872
self.full_screen_mode_active = bool(toBool(settings.value("fullscreen",self.full_screen_mode_active)))
18867-
#PLUS
18868-
if settings.contains("plus_account"):
18869-
self.plus_account = settings.value("plus_account",self.plus_account)
18870-
self.plus_remember_credentials = bool(toBool(settings.value("plus_remember_credentials",self.plus_remember_credentials)))
18871-
if self.plus_account is not None:
18872-
try:
18873-
import plus.controller
18874-
plus.controller.start(aw)
18875-
except:
18876-
pass
18873+
18874+
#PLUS-COMMENT
18875+
# if settings.contains("plus_account"):
18876+
# self.plus_account = settings.value("plus_account",self.plus_account)
18877+
# self.plus_remember_credentials = bool(toBool(settings.value("plus_remember_credentials",self.plus_remember_credentials)))
18878+
# if self.plus_account is not None:
18879+
# try:
18880+
# import plus.controller
18881+
# plus.controller.start(aw)
18882+
# except:
18883+
# pass
1887718884

1887818885
#restore mode
1887918886
old_mode = self.qmc.mode
@@ -19956,7 +19963,7 @@ def settingsLoad(self, filename=None):
1995619963
else:
1995719964
self.recentRoasts = []
1995819965
self.updateNewMenuRecentRoasts()
19959-
except:
19966+
except Exception:
1996019967
pass
1996119968

1996219969
# #update axis limits
@@ -28051,6 +28058,13 @@ def __init__(self, parent = None):
2805128058
self.setModal(True)
2805228059
self.setWindowTitle(QApplication.translate("Form Caption","Roast Properties",None))
2805328060

28061+
# remember parameters related to plus_coffee/plus_blend
28062+
# if any of those changed manually while in non-plus mode, plus_coffee, plus_blend an plus_stock needs to be reset
28063+
self.org_beans = aw.qmc.beans
28064+
self.org_density = aw.qmc.density
28065+
self.org_beansize_min = aw.qmc.beansize_min
28066+
self.org_beansize_max = aw.qmc.beansize_max
28067+
self.org_moisture_greens = aw.qmc.moisture_greens
2805428068

2805528069
self.org_specialevents = aw.qmc.specialevents
2805628070
self.org_specialeventstype = aw.qmc.specialeventstype
@@ -28651,7 +28665,7 @@ def __init__(self, parent = None):
2865128665
titleLine.addSpacing(5)
2865228666
titleLine.addWidget(self.titleShowAlwaysFlag)
2865328667

28654-
#PLUS (keep)
28668+
#PLUS
2865528669
self.plus_store_selected = None
2865628670
self.plus_coffee_selected = None
2865728671
self.plus_blend_selected = None
@@ -28673,7 +28687,7 @@ def __init__(self, parent = None):
2867328687
self.plus_stores_combo = QComboBox()
2867428688
self.plus_coffees_combo = QComboBox()
2867528689
self.plus_blends_combo = QComboBox()
28676-
self.populatePlusCoffeeBlendCombos()
28690+
self.populatePlusCoffeeBlendCombos()
2867728691
self.plus_stores_combo.currentIndexChanged.connect(self.storeSelectionChanged)
2867828692
self.plus_coffees_combo.currentIndexChanged.connect(self.coffeeSelectionChanged)
2867928693
self.plus_blends_combo.currentIndexChanged.connect(self.blendSelectionChanged)
@@ -28965,6 +28979,11 @@ def populatePlusCoffeeBlendCombos(self,storeIndex=None):
2896528979
self.plus_stores_combo.blockSignals(False)
2896628980

2896728981
storeIdx = self.plus_stores_combo.currentIndex()
28982+
28983+
# we reset the store if a coffee or blend is selected and the selected store is not equal to the default store
28984+
if (self.plus_coffee_selected or self.plus_blend_selected) and self.plus_store_selected != plus.stock.getStoreId(self.plus_stores[storeIdx-1]):
28985+
storeIdx = None
28986+
2896828987
if storeIdx:
2896928988
self.plus_default_store = plus.stock.getStoreId(self.plus_stores[storeIdx-1])
2897028989
else:
@@ -28983,7 +29002,7 @@ def populatePlusCoffeeBlendCombos(self,storeIndex=None):
2898329002
if p is None:
2898429003
self.plus_coffees_combo.setCurrentIndex(0)
2898529004
if self.plus_blend_selected is None:
28986-
self.beansedit.setReadOnly(False)
29005+
self.setReadOnlyPlusBlendFields(False)
2898729006
self.plus_coffee_selected = None
2898829007
self.plus_coffees_combo.blockSignals(False)
2898929008
else:
@@ -29011,7 +29030,7 @@ def populatePlusCoffeeBlendCombos(self,storeIndex=None):
2901129030
if p is None:
2901229031
self.plus_blends_combo.setCurrentIndex(0)
2901329032
if self.plus_coffee_selected is None:
29014-
self.beansedit.setReadOnly(False)
29033+
self.setReadOnlyPlusCoffeeFields(False)
2901529034
self.plus_blend_selected = None
2901629035
self.plus_blends_combo.blockSignals(False)
2901729036
else:
@@ -29025,6 +29044,20 @@ def populatePlusCoffeeBlendCombos(self,storeIndex=None):
2902529044
self.plus_blends_combo.blockSignals(False)
2902629045
self.plus_blends_combo.setCurrentIndex(p+1)
2902729046

29047+
def setReadOnlyPlusCoffeeFields(self,b):
29048+
self.beansedit.setReadOnly(b)
29049+
self.bean_density_weightUnitsComboBox.setDisabled(b)
29050+
self.bean_density_volumeUnitsComboBox.setDisabled(b)
29051+
self.bean_density_weight_edit.setReadOnly(b)
29052+
self.bean_density_volume_edit.setReadOnly(b)
29053+
self.bean_density_weight_edit.setReadOnly(b)
29054+
self.bean_size_min_edit.setReadOnly(b)
29055+
self.bean_size_max_edit.setReadOnly(b)
29056+
self.moisture_greens_edit.setReadOnly(b)
29057+
29058+
def setReadOnlyPlusBlendFields(self,b):
29059+
self.beansedit.setReadOnly(b)
29060+
2902829061
def fillBlendData(self,blend):
2902929062
import plus.stock
2903029063
try:
@@ -29036,6 +29069,7 @@ def fillBlendData(self,blend):
2903629069
self.beansedit.clear()
2903729070
for l in blend_lines:
2903829071
self.beansedit.append(l)
29072+
self.setReadOnlyPlusBlendFields(True)
2903929073
except:
2904029074
pass
2904129075

@@ -29067,17 +29101,17 @@ def fillCoffeeData(self,coffee):
2906729101
else:
2906829102
self.bean_size_min_edit.setText("0")
2906929103
self.bean_size_max_edit.setText("0")
29070-
self.standard_density()
29071-
self.beansedit.setReadOnly(True)
29104+
self.standard_density()
29105+
self.setReadOnlyPlusCoffeeFields(True)
2907229106

2907329107
def defaultCoffeeData(self):
2907429108
self.beansedit.setPlainText("")
29075-
self.beansedit.setReadOnly(False)
2907629109
self.moisture_greens_edit.setText(str(0))
2907729110
self.bean_density_weight_edit.setText(str(0))
2907829111
self.standard_density()
2907929112
self.bean_size_min_edit.setText("0")
2908029113
self.bean_size_max_edit.setText("0")
29114+
self.setReadOnlyPlusCoffeeFields(False)
2908129115

2908229116
def storeSelectionChanged(self,n):
2908329117
if n != -1:
@@ -30225,6 +30259,15 @@ def accept(self):
3022530259
aw.qmc.roastbatchprefix = u(self.batchprefixedit.text())
3022630260
aw.qmc.roastbatchnr = self.batchcounterSpinBox.value()
3022730261
aw.qmc.roastbatchpos = self.batchposSpinBox.value()
30262+
30263+
# Reset Plus if any of the plus_coffee related values changed
30264+
if aw.plus_account is None and aw.qmc.plus_coffee is not None and (self.org_beans != aw.qmc.beans or self.org_density != aw.qmc.density or \
30265+
self.org_beansize_min != aw.qmc.beansize_min or self.org_beansize_max != aw.qmc.beansize_max or \
30266+
self.org_moisture_greens != aw.qmc.moisture_greens):
30267+
aw.qmc.plus_coffee = None
30268+
if aw.plus_account is None and aw.qmc.plus_blend is not None and self.org_beans != aw.qmc.beans:
30269+
aw.qmc.plus_blend = None
30270+
3022830271
aw.sendmessage(QApplication.translate("Message","Roast properties updated but profile not saved to disk", None))
3022930272
aw.qmc.redraw(recomputeAllDeltas=False)
3023030273
self.close()
@@ -45002,12 +45045,11 @@ def addalarm(self):
4500245045
self.setalarmtablerow(nalarms)
4500345046

4500445047
header = self.alarmtable.horizontalHeader()
45005-
header.setStretchLastSection(False)
45048+
header.setStretchLastSection(True)
4500645049

4500745050
if len(aw.qmc.alarmflag) == 1: # only for the first entry we apply some default column width
45008-
self.alarmtable.resizeColumnsToContents()
45009-
self.alarmtable.resizeRowsToContents()
4501045051
# improve width of Qlineedit columns
45052+
self.alarmtable.resizeColumnsToContents()
4501145053
self.alarmtable.setColumnWidth(1,50)
4501245054
self.alarmtable.setColumnWidth(2,50)
4501345055
self.alarmtable.setColumnWidth(3,50)
@@ -45016,13 +45058,14 @@ def addalarm(self):
4501645058
self.alarmtable.setColumnWidth(6,70)
4501745059
self.alarmtable.setColumnWidth(7,90)
4501845060
self.alarmtable.setColumnWidth(8,50)
45019-
self.alarmtable.setColumnWidth(9,90)
45061+
self.alarmtable.setColumnWidth(9,90)
4502045062
# remember the columnwidth
4502145063
for i in range(len(aw.qmc.alarmtablecolumnwidths)):
4502245064
try:
4502345065
self.alarmtable.setColumnWidth(i,aw.qmc.alarmtablecolumnwidths[i])
4502445066
except:
4502545067
pass
45068+
self.alarmtable.setSortingEnabled(True)
4502645069
else:
4502745070
self.deselectAll()
4502845071
# select newly added row i.e. the last one

src/artisanlib/modbusport.py

+1
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ def writeCoil(self,slave,register,value):
310310
# write value to register on slave (function 6 for int or function 16 for float)
311311
# value can be one of string (containing an int or float), an int or a float
312312
def writeRegister(self,slave,register,value):
313+
# print("writeRegister",slave,register,value)
313314
if stringp(value):
314315
if "." in value:
315316
self.writeWord(slave,register,value)

src/build-mac3.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ else
3030
export PYTHONPATH=$PYTHON/lib/python3.7
3131
export PYTHON_V=3.7
3232
export QT_PATH=${PYTHONPATH}/site-packages/PyQt5/Qt
33-
export QT_SRC_PATH=~/Qt5.11.1/5.11.1/clang_64
33+
export QT_SRC_PATH=~/Qt5.11.2/5.11.2/clang_64
3434
export MACOSX_DEPLOYMENT_TARGET=10.13
3535
export DYLD_LIBRARY_PATH=$PYTHON/lib:$DYLD_LIBRARY_PATH
3636
export ARTISAN_LEGACY_BUILD=false

src/debian/usr/share/doc/artisan/changelog

+16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
artisan (1.4.0-0) precise; urgency=low
2+
* new upstream release
3+
* changes since 1.3.1:
4+
- adds time guide
5+
- adds additional PhasesLCD configurations
6+
- adds export/convert to Excel and import/export to Probat Pilot v1.4
7+
- adds channel tare
8+
- adds playback DROP event
9+
- adds always ON mode
10+
- adds support for ambient data and Phidget ambient sensors HUM1000 and PRE1000
11+
- adds PID P-on-Measurement/Input mode
12+
- adds improved curve smoothing
13+
- adds additional machine support for Atilla GOLD plus 7", Besca roasting machines, Coffee-Tech Engineering Ghibli and Diedrich Roasters
14+
- bug fixes
15+
-- <[email protected]> Wed, 3 Oct 2018 19:32:14 +0200
16+
117
artisan (1.3.1-0) precise; urgency=low
218
* new upstream release
319
* changes since 1.3.0:

src/includes/Machines/Atilla/GOLD_plus_7''.aset

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ input6float=false
6161
input6mode=C
6262
input6register=0
6363
input6slave=0
64-
littleEndianFloats=true
64+
littleEndianFloats=false
6565
parity=N
6666
port=502
6767
stopbits=1

0 commit comments

Comments
 (0)