From af3316c0e9928eac915d45b3ec35b64789414329 Mon Sep 17 00:00:00 2001 From: Aeva Palecek Date: Sun, 7 Apr 2024 00:13:31 -0500 Subject: [PATCH 1/4] Convert Print Statements to Print Functions Python 2.7 hasn't been maintained in over 6,000 years. It's time. --- README.md | 6 +++--- csafe_cmd.py | 18 +++++++++--------- pyrow.py | 4 ++-- statshow.py | 8 ++++---- strokelog.py | 8 ++++---- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index b59f828..525a080 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Licensed under the Simplified BSD License. PyRow has been tested on an Ubuntu machine with the software versions listed below, PyRow should be able to work on any machine that can run Python & PyUSB but this has not been tested and confirmed. -- [Python](http://python.org/) (Tested with 2.7.2) +- [Python](http://python.org/) - [libusb](http://www.libusb.org/) sudo apt-get install libudev-dev libusb-dev python @@ -169,8 +169,8 @@ ex: getting pace and printing it out command = ['CSAFE_GETPACE_CMD',] result = erg.send(command) - print "Stroke Pace = " + str(result['CSAFE_GETPACE_CMD'][0]) - print "Stroke Units = " + str(result['CSAFE_GETPACE_CMD'][1]) + print("Stroke Pace = " + str(result['CSAFE_GETPACE_CMD'][0])) + print("Stroke Units = " + str(result['CSAFE_GETPACE_CMD'][1])) ## FILES diff --git a/csafe_cmd.py b/csafe_cmd.py index b686327..235a82d 100755 --- a/csafe_cmd.py +++ b/csafe_cmd.py @@ -1,10 +1,10 @@ -#ToDo: change print statments to proper errors +#ToDo: change print() calls to proper errors import csafe_dic def __int2bytes(numbytes, integer): if not 0 <= integer <= 2 ** (8 * numbytes): - print "Integer is outside the allowable range" + print("Integer is outside the allowable range") byte = [] for k in range(numbytes): @@ -122,7 +122,7 @@ def write(arguments): #check for frame size (96 bytes) if len(message) > 96: - print "Message is too long: " + len(message) + print("Message is too long: " + len(message)) #report IDs maxmessage = max(len(message) + 1, maxresponse) @@ -137,9 +137,9 @@ def write(arguments): message.insert(0, 0x02) message += [0] * (121 - len(message)) if maxresponse > 121: - print "Response may be too long to recieve. Max possible length " + str(maxresponse) + print("Response may be too long to recieve. Max possible length " + str(maxresponse)) else: - print "Message too long. Message length " + str(len(message)) + print("Message too long. Message length " + str(len(message))) message = [] return message @@ -164,7 +164,7 @@ def __check_message(message): #checks checksum if checksum != 0: - print "Checksum error" + print("Checksum error") return [] #remove checksum from end of message @@ -188,7 +188,7 @@ def read(transmission): elif startflag == csafe_dic.Standard_Frame_Start_Flag: j = 2 else: - print "No Start Flag found." + print("No Start Flag found.") return [] while j < len(transmission): @@ -199,7 +199,7 @@ def read(transmission): j += 1 if not stopfound: - print "No Stop Flag found." + print("No Stop Flag found.") return [] message = __check_message(message) @@ -247,7 +247,7 @@ def read(transmission): #checking that the recieved data byte is the expected length, sanity check if abs(sum(msgprop[1])) != 0 and bytecount != abs(sum(msgprop[1])): - print "Warning: bytecount is an unexpected length" + print("Warning: bytecount is an unexpected length") #extract values for numbytes in msgprop[1]: diff --git a/pyrow.py b/pyrow.py index 90769a8..31159c7 100755 --- a/pyrow.py +++ b/pyrow.py @@ -31,9 +31,9 @@ def __init__(self, erg): if erg.is_kernel_driver_active(INTERFACE): erg.detach_kernel_driver(INTERFACE) else: - print "DEBUG: usb kernel driver not on " + sys.platform + print("DEBUG: usb kernel driver not on " + sys.platform) except: - print "EXCEPTION" + print("EXCEPTION") #Claim interface (Needs Testing To See If Necessary) usb.util.claim_interface(erg, INTERFACE) diff --git a/statshow.py b/statshow.py index 96124f8..6d99cb5 100755 --- a/statshow.py +++ b/statshow.py @@ -7,7 +7,7 @@ if len(ergs) == 0: exit("No ergs found.") erg = pyrow.pyrow(ergs[0]) - print "Connected to erg." + print("Connected to erg.") #Create a dictionary of the different status states state = ['Error', 'Ready', 'Idle', 'Have ID', 'N/A', 'In Use', @@ -35,11 +35,11 @@ results = erg.send(command) if cstate != (results['CSAFE_GETSTATUS_CMD'][0] & 0xF): cstate = results['CSAFE_GETSTATUS_CMD'][0] & 0xF - print "State " + str(cstate) + ": " + state[cstate] + print("State " + str(cstate) + ": " + state[cstate]) if cstroke != results['CSAFE_PM_GET_STROKESTATE'][0]: cstroke = results['CSAFE_PM_GET_STROKESTATE'][0] - print "Stroke " + str(cstroke) + ": " + stroke[cstroke] + print("Stroke " + str(cstroke) + ": " + stroke[cstroke]) if cworkout != results['CSAFE_PM_GET_WORKOUTSTATE'][0]: cworkout = results['CSAFE_PM_GET_WORKOUTSTATE'][0] - print "Workout " + str(cworkout) + ": " + workout[cworkout] + print("Workout " + str(cworkout) + ": " + workout[cworkout]) time.sleep(1) diff --git a/strokelog.py b/strokelog.py index 06eae2f..ff895dc 100755 --- a/strokelog.py +++ b/strokelog.py @@ -9,7 +9,7 @@ exit("No ergs found.") erg = pyrow.pyrow(ergs[0]) - print "Connected to erg." + print("Connected to erg.") #Open and prepare file write_file = open('workout.csv', 'w') @@ -17,11 +17,11 @@ #Loop until workout has begun workout = erg.get_workout() - print "Waiting for workout to start ..." + print("Waiting for workout to start ...") while workout['state'] == 0: time.sleep(1) workout = erg.get_workout() - print "Workout has begun" + print("Workout has begun") #Loop until workout ends while workout['state'] == 1: @@ -57,4 +57,4 @@ workout = erg.get_workout() write_file.close() - print "Workout has ended" + print("Workout has ended") From 78735939dc627e8664dfafc9b4d69cbc4df2dec6 Mon Sep 17 00:00:00 2001 From: Aeva Palecek Date: Sun, 7 Apr 2024 00:39:32 -0500 Subject: [PATCH 2/4] Disable Obsolete 63 Byte Report Per Firmware Author's Advice This change applies the fix recommended by @mlyonupdesigns here: https://github.com/wemakewaves/PyRow/issues/5 Page 6 of the PM5 CSAFE specification indicates that the spec was revised on 04/06/23 by Mark Lyons, which is likely the change mentioned in the linked issue: Changed USB report ID 4 size from 62 to 500 bytes; added some a dditonal enumeration definitions; V0.26 See: https://www.concept2.com/files/pdf/us/monitors/PM5_CSAFECommunicationDefinition.pdf This change is said to be necessary for compatibility with PM5 ergs, which happens to be what I have on hand. I have confirmed that this commit enables the statshow.log command to function correctly with a PM5 Concept2 RowErg. Additional information: I am runing this on NixOS over USB with 3.13. --- csafe_cmd.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/csafe_cmd.py b/csafe_cmd.py index 235a82d..235bb7c 100755 --- a/csafe_cmd.py +++ b/csafe_cmd.py @@ -130,9 +130,10 @@ def write(arguments): if maxmessage <= 21: message.insert(0, 0x01) message += [0] * (21 - len(message)) - elif maxmessage <= 63: - message.insert(0, 0x04) - message += [0] * (63 - len(message)) + ## see https://github.com/wemakewaves/PyRow/issues/5 + #elif maxmessage <= 63: + # message.insert(0, 0x04) + # message += [0] * (63 - len(message)) elif (len(message) + 1) <= 121: message.insert(0, 0x02) message += [0] * (121 - len(message)) From 7e3aaf87cb2cf9da858b1263997eb9a1845d3061 Mon Sep 17 00:00:00 2001 From: Aeva Palecek Date: Sun, 7 Apr 2024 00:50:18 -0500 Subject: [PATCH 3/4] Python 3 Floor Divide For Indexing Arithmetic --- pyrow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrow.py b/pyrow.py index 31159c7..de11d9d 100755 --- a/pyrow.py +++ b/pyrow.py @@ -116,7 +116,7 @@ def get_force_plot(self): results = self.send(command) forceplot = {} - datapoints = results['CSAFE_PM_GET_FORCEPLOTDATA'][0] / 2 + datapoints = results['CSAFE_PM_GET_FORCEPLOTDATA'][0] // 2 forceplot['forceplot'] = results['CSAFE_PM_GET_FORCEPLOTDATA'][1:(datapoints+1)] forceplot['strokestate'] = results['CSAFE_PM_GET_STROKESTATE'][0] From c008ce54e57e8d7bbfc8f854f814d1bd8b213aab Mon Sep 17 00:00:00 2001 From: Aeva Palecek Date: Sun, 7 Apr 2024 00:54:11 -0500 Subject: [PATCH 4/4] Correct Protocol Documentation Links in Readme This resolves https://github.com/wemakewaves/PyRow/issues/6 --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 525a080..0839e51 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,9 @@ PyRow is python code that allows one to interact with a Concept 2 Rowing Ergomet For an explanation of the csafe commands please use the following documentation: -- [Concept2 PM Communication Interface Definition](http://www.concept2.com/service/software/software-development-kit) +- [Concept2 PM Communication Interface Definition](https://www.concept2.com/files/pdf/us/monitors/PM5_CSAFECommunicationDefinition.pdf) -_Need to download the SDK to get the document_ - -- [Communications Specification for Fitness Equipment](http://www.fitlinxx.com/CSAFE/) +- [Communications Specification for Fitness Equipment](https://web.archive.org/web/20080614002257/http://www.fitlinxx.com/CSAFE/) Site: http://www.newhavenrowingclub.org/pyrow/