Skip to content

Commit

Permalink
adds support for the Phidget RCC0004 servo controller
Browse files Browse the repository at this point in the history
  • Loading branch information
MAKOMO committed May 2, 2024
1 parent 3389da0 commit 557811e
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 13 deletions.
5 changes: 3 additions & 2 deletions src/artisanlib/alarms.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@
from PyQt6.QtGui import QColor, QIntValidator # @UnusedImport @Reimport @UnresolvedImport
from PyQt6.QtWidgets import (QApplication, QWidget, QLabel, QLineEdit, QComboBox, QDialogButtonBox, # @UnusedImport @Reimport @UnresolvedImport
QTableWidget, QHBoxLayout, QVBoxLayout, QCheckBox, QPushButton, QSizePolicy, QSpinBox, # @UnusedImport @Reimport @UnresolvedImport
QTableWidgetSelectionRange, QTimeEdit, QTabWidget, QGridLayout, QGroupBox, QHeaderView, QStyledItemDelegate) # @UnusedImport @Reimport @UnresolvedImport
QTableWidgetSelectionRange, QTimeEdit, QTabWidget, QGridLayout, QGroupBox, QHeaderView, QStyledItemDelegate, QAbstractSpinBox) # @UnusedImport @Reimport @UnresolvedImport
except ImportError:
from PyQt5.QtCore import (Qt, pyqtSlot, QSettings, QTimer) # type: ignore # @UnusedImport @Reimport @UnresolvedImport
from PyQt5.QtGui import QColor, QIntValidator # type: ignore # @UnusedImport @Reimport @UnresolvedImport
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QLineEdit, QComboBox, QDialogButtonBox, # type: ignore # @UnusedImport @Reimport @UnresolvedImport
QTableWidget, QHBoxLayout, QVBoxLayout, QCheckBox, QPushButton, QSizePolicy, QSpinBox, # # @UnusedImport @Reimport @UnresolvedImport
QTableWidgetSelectionRange, QTimeEdit, QTabWidget, QGridLayout, QGroupBox, QHeaderView, QStyledItemDelegate) # @UnusedImport @Reimport @UnresolvedImport
QTableWidgetSelectionRange, QTimeEdit, QTabWidget, QGridLayout, QGroupBox, QHeaderView, QStyledItemDelegate, QAbstractSpinBox) # @UnusedImport @Reimport @UnresolvedImport



Expand Down Expand Up @@ -854,6 +854,7 @@ def setalarmtablerow(self, i:int) -> None:
timeoffsetedit.setAlignment(Qt.AlignmentFlag.AlignRight)
timeoffsetedit.setDisplayFormat('mm:ss')
timeoffsetedit.setTime(self.aw.time2QTime(max(0,self.aw.qmc.alarmoffset[i])))
timeoffsetedit.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
#6: type/source
typeComboBox = MyQComboBox()
typeComboBox.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
Expand Down
16 changes: 13 additions & 3 deletions src/artisanlib/comm.py
Original file line number Diff line number Diff line change
Expand Up @@ -5109,7 +5109,12 @@ def yoctoSERVOclose(self) -> None:


#--- Phidget RC (only one supported for now)
# supporting up to 16 channels like those of the RCC1000
# supporting up to 16 channels for the following RC Phidgets
# - Phidget RCC1000: 16 channels (RC Servo Phidget)
# - Phidget RCC1061: 8 channels (AdvancedServo 8-Motor)
# - Phidget RCC0004: 8 channels (AdvancedServo 8-Motor)
# - Phidget RCC1066: 1 channels (AdvancedServo 1-Motor)

# commands:
# pulse(ch,min,max[,sn]) # sets min/max pulse width
# pos(ch,min,max[,sn]) # sets min/max position
Expand All @@ -5132,12 +5137,17 @@ def phidgetRCattach(self, channel:int, serial:Optional[str]=None) -> None:
ser,port = self.aw.qmc.phidgetManager.getFirstMatchingPhidget('PhidgetRCServo',DeviceID.PHIDID_RCC1000,
remote=self.aw.qmc.phidgetRemoteFlag,remoteOnly=self.aw.qmc.phidgetRemoteOnlyFlag,serial=s,hubport=p)
ports = 16
# try to attach an Phidget RC 1061 module
# try to attach an Phidget RCC0004 module
if ser is None:
ser,port = self.aw.qmc.phidgetManager.getFirstMatchingPhidget('PhidgetRCServo',DeviceID.PHIDID_RCC0004,
remote=self.aw.qmc.phidgetRemoteFlag,remoteOnly=self.aw.qmc.phidgetRemoteOnlyFlag,serial=s,hubport=p)
ports = 8
# try to attach an Phidget RCC1061 module
if ser is None:
ser,port = self.aw.qmc.phidgetManager.getFirstMatchingPhidget('PhidgetRCServo',DeviceID.PHIDID_1061,
remote=self.aw.qmc.phidgetRemoteFlag,remoteOnly=self.aw.qmc.phidgetRemoteOnlyFlag,serial=s,hubport=p)
ports = 8
# try to attach an Phidget RC 1066 module
# try to attach an Phidget RCC1066 module
if ser is None:
ser,port = self.aw.qmc.phidgetManager.getFirstMatchingPhidget('PhidgetRCServo',DeviceID.PHIDID_1066,
remote=self.aw.qmc.phidgetRemoteFlag,remoteOnly=self.aw.qmc.phidgetRemoteOnlyFlag,serial=s,hubport=p)
Expand Down
4 changes: 3 additions & 1 deletion src/artisanlib/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ def appRaised(self, oldFocusWidget:Optional[QWidget], newFocusWidget:Optional[QW
plus.sync.getUpdate(aw.qmc.roastUUID,aw.curFile)
except Exception as e: # pylint: disable=broad-except
_log.exception(e)
aw.updateScheduleSignal.emit()
self.sentToBackground = None

elif oldFocusWidget is not None and newFocusWidget is None and aw is not None and aw.centralWidget() == oldFocusWidget:
Expand Down Expand Up @@ -5139,7 +5140,7 @@ def populateListMenu(self, resourceName:str, ext:str, triggered:Callable[[bool],
res[d] = []
res[d].append((f,p))
keys = list(res.keys())
keys.sort()
keys.sort(key=lambda v: (v.upper(), v[0].islower()))
for k in keys:
if len(res[k]) > 1:
if len(keys) == 1 and not forceSubmenu:
Expand Down Expand Up @@ -11054,6 +11055,7 @@ def togglePlaybackEvents(self) -> None:
self.updatePlaybackIndicatorSignal.emit()

#keyboard presses. There must not be widgets (pushbuttons, comboboxes, etc) in focus in order to work
@pyqtSlot('QKeyEvent')
def keyPressEvent(self, event: Optional['QKeyEvent']) -> None:
if not self.processingKeyEvent and event is not None:
try:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Delay=1000
ExtraEventSamplingDelay=0
Oversampling=false
roastertype_setup=IP Xenakis iRm
roastertype_setup=iRm Series Mitsubishi

[ArduinoPID]
dutyMax=100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Delay=1000
ExtraEventSamplingDelay=0
Oversampling=false
roastertype_setup=IP Xenakis iRm
roastertype_setup=iRm Series Omron

[ArduinoPID]
dutyMax=100
Expand Down
9 changes: 6 additions & 3 deletions src/plus/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,8 @@ def applyServerUpdates(data:Dict[str, Any]) -> None:

# internal function fetching the update from server and then unblock the
# Properties Dialog and update the plus icon
def fetchServerUpdate(uuid: str, file:Optional[str]=None) -> None:
# if return_data is set, the received data is not applied via applyServerUpdates, but returned instead
def fetchServerUpdate(uuid: str, file:Optional[str]=None, return_data:bool = False) -> Optional[Dict[str, Any]]:
assert config.app_window is not None
aw = config.app_window
import requests
Expand Down Expand Up @@ -729,15 +730,16 @@ def fetchServerUpdate(uuid: str, file:Optional[str]=None) -> None:
data = res.json()
util.updateLimitsFromResponse(data) # update account limits
if 'result' in data:
r = data['result']
r:Dict[str, Any] = data['result']
_log.debug('-> fetch: %s', r)

if getSync(uuid) is None and 'modified_at' in r:
addSync(uuid, util.ISO86012epoch(r['modified_at']))
_log.debug(
'-> added profile automatically to sync cache'
)

if return_data:
return r
if file_last_modified is not None:
_log.debug(
'-> file last_modified date: %s',
Expand Down Expand Up @@ -782,6 +784,7 @@ def fetchServerUpdate(uuid: str, file:Optional[str]=None) -> None:
# syncing from the server
aw.editgraphdialog = None
config.app_window.updatePlusStatusSignal.emit() # @UndefinedVariable
return None


# updates from server are only requested if connected (the uuid does not have
Expand Down
2 changes: 1 addition & 1 deletion src/requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ types-urllib3>=1.26.25.14
types-Pillow>=10.2.0.20240423
lxml-stubs>=0.5.1
mypy==1.10.0
pyright==1.1.360
pyright==1.1.361
ruff>=0.4.2
pylint==3.1.0
pre-commit>=3.6.2
Expand Down
3 changes: 2 additions & 1 deletion wiki/ReleaseHistory.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ v2.10.6 (XX, 2024)

* NEW HARDWARE SUPPORT
- adds setups for machines [IP CC machines]() featuring a Mitshubishi PLCs
- adds Bühler RM20 Simatic Legacy setup supporting older firmware versions not returning the machine state
- adds [Bühler RM20](https://www.buhlergroup.com/global/de/products/roastmaster_coffeeroaster.html) Simatic Legacy setup supporting older firmware versions not returning the machine state
- adds support for the [Phidget RCC0004 server motor controller](https://phidgets.com/?prodid=1147) ([Discussion #1546](../../../discussions/1546))

* CHANGES
- only reset roasting notes on reset if profile is loaded ([Issue #1521](../../../issues/1521))
Expand Down

0 comments on commit 557811e

Please sign in to comment.