B
    ^K?                 @   s   d Z ddlZddlZddlZddlZddlZddlmZ ddlm	Z	 dZ
dZdZddd	d
dgddddddddgddddddddddddd d!gd"d#d$gd%d&d'd(d)d*gd+d,d-d.gd/d0d1d2d3d4d5d6d7d8g
d9Zd:d; Zd<d= Zd>d? ZG d@dA dAeZdS )Bz-
pyrow.py
Interface to concept2 indoor rower
    N)USBError)	csafe_cmdi  g?zWait for min speedzWait for accelerationZDriveZDwellingZRecoveryzJust Row / no splitszJust Row / splitszFixed Distance / splitszFixed Distance / no splitszFixed Time / no splitszFixed Time IntervalzFixed Distance IntervalzVariable IntervalzWaiting beginzWorkout rowzCountdown pausezInterval restzWork time invervalzWork distance intervalzRest end timezRest end distancezTime end restzDistance end restzWorkout endzWorkout terminatezWorkout loggedzWorkout rearmTimeDistanceZRestZStandardzForce/VelocityZPaceboatz
Per StrokeZSimpleZTargetzTime/MetersZPaceZWattsZCaloriesErrorZReadyZIdlezHave IDzN/AzIn UseZPauseZFinishedZManualZOffline)strokestateZworkouttypeZworkoutstateinttypeZdisplaytypeZdisplayunitstypestatusc             C   s8   t | tst|||   kr&|ks4n t|d dS )zH
    Checks that value is an integer and within the specified range
    z outside of rangeT)
isinstanceint	TypeError
ValueError)valueZlabelZminimumZmaximum r   /var/underergo/pyrow/pyrow.py
checkvalueg   s
    
r   c          	   C   sP   |rLxF|   D ]:}|tkryt| | |  | |< W q tk
rF   Y qX qW | S )z'
    Makes data_dict values pretty
    )keysERG_MAPPING
IndexError)	data_dictprettykeyr   r   r   
get_prettyq   s    
r   c           
   C   s^   yt jjdtd} W n4 tk
rH } z|jdkr8tdW dd}~X Y nX | dkrZtd| S )z7
    Returns list of pyusb Devices which are ergs.
    T)Zfind_allZidVendor   zUSB busyNzErgs not found)usbZcorefindC2_VENDOR_IDr   errnoConnectionRefusedErrorr   )Zergser   r   r   r      s    
r   c               @   sp   e Zd ZdZdd Zedd ZdddZdd	d
ZdddZ	dddZ
dddZdd ZdddZdd ZdS )PyErgz-
    Manages low-level erg communication
    c          
   C   s   ddl m} tjdkrPy*|tr.|t n|dtj W n    Y nX tj	
|t y|  W n0 tk
r } z|d| W dd}~X Y nX || _|d }|d }|d j| _|d j| _tj | _dS )	z>
        Configures usb connection and sets erg value
        r   )warnwin32z"DEBUG: usb kernel driver not on {}z1DEBUG: usb error whilst setting configuration, {}N)r   r      )warningsr!   sysplatformZis_kernel_driver_active	INTERFACEZdetach_kernel_driverformatr   utilZclaim_interfaceZset_configurationr   ergZbEndpointAddress
inEndpointoutEndpointdatetimenow_PyErg__lastsend)selfr*   r!   r   ZconfigurationZifacer   r   r   __init__   s&    

 zPyErg.__init__c              O   s
   t | |S )N)r   )argskwargsr   r   r   _checkvalue   s    zPyErg._checkvalueFc       	      C   s  dddddddg}|r&| dd	d
g | |}dddddddddddg}| |}ddg}| |}i }||d< ||d< ||d< |d d |d d  d |d< |d d |d d  d |d < |d d |d!< |d d |d"< |d" r"d#|d d  d$ d% |d&< |d d d' d( |d)< nd*\|d&< |d)< |d d |d+< |d d |d,< |r|d d d- }|d d|d  |d.< |d
 d |d/< |d d d0@ |d1< t||}|S )2a  
        Returns values from the monitor that relate to the current workout,
        optionally returns force plot data and stroke state. (* required)
        time: time in seconds
        distance: distance in meters
        spm: strokes per minute
        power: power in watts
        pace: seconds/500m
        calhr: calories burned per hour
        calories: calories burned
        heartrate: heartrate
        status
        if heartrate:
            forceplot: force plot data
            strokestate
        ZCSAFE_PM_GET_WORKTIMEZCSAFE_PM_GET_WORKDISTANCEZCSAFE_GETCADENCE_CMDZCSAFE_GETPOWER_CMDZCSAFE_GETCALORIES_CMDZCSAFE_GETHRCUR_CMDZCSAFE_PM_GET_DRAGFACTORCSAFE_PM_GET_FORCEPLOTDATA    CSAFE_PM_GET_STROKESTATEZCSAFE_GETODOMETER_CMDZCSAFE_PM_GET_RESTTIMEZCSAFE_GETPACE_CMDZCSAFE_GETUSERINFO_CMDZCSAFE_GETHORIZONTAL_CMDZCSAFE_GETPROGRAM_CMDCSAFE_GETSERIAL_CMDZCSAFE_GETUNITS_CMDCSAFE_GETID_CMDCSAFE_GETVERSION_CMDCSAFE_GETSTATUS_CMDZCSAFE_PM_GET_STROKESTATSr   resultsresults2results3r   r#   g      Y@timeg      $@distanceZspmZpowergffffff@gUUUUUU?i  pacegOe@g     r@Zcalhr)r   r   ZcaloriesZ	heartrate   	forceplotr      r	   )extendsendr   )	r0   rC   r   commandr<   r=   r>   Zmonitor
datapointsr   r   r   get_monitor   sF    






zPyErg.get_monitorc             C   sr   dddg}|  |}i }|d d d }|d d|d  |d< |d d |d< |d	 d d
@ |d< t||}|S )z:
        Returns force plot data and stroke state
        r5   r6   r7   r   rB   r#   rC   r   r;   rD   r	   )rF   r   )r0   r   rG   r<   rC   rH   r   r   r   get_forceplot	  s    


zPyErg.get_forceplotc             C   s   dddddg}|  |}i }|d d |d< |d d |d< |d d |d	< |d d |d
< |d d |d< |d d d@ |d< t||}|S )z.
        Returns overall workout data
        r9   ZCSAFE_PM_GET_WORKOUTTYPEZCSAFE_PM_GET_WORKOUTSTATEZCSAFE_PM_GET_INTERVALTYPEZ!CSAFE_PM_GET_WORKOUTINTERVALCOUNTr   Zuseridtypestater   Zintcountr;   rD   r	   )rF   r   )r0   r   rG   r<   Zworkoutdatar   r   r   get_workout  s    

zPyErg.get_workoutc             C   s   ddddg}|  |}i }|d d |d< |d d |d< |d d |d	< |d d
 |d< |d d |d< |d d |d< |d d |d< |d d |d< |d d |d< |d d d@ |d< t||}|S )zI
        Returns all erg data that is not related to the workout
        r:   r8   ZCSAFE_GETCAPS_CMDr   Zmfgidr#   ZcidrB   Zmodel   Z	hwversion   Z	swversionserialZmaxrxZmaxtxZmininterframer;   rD   r	   )rF   r   )r0   r   rG   r<   Zergdatar   r   r   get_erg1  s    

zPyErg.get_ergc             C   s6   dg}|  |}i }|d d d@ |d< t||}|S )z/
        Returns the status of the erg
        r;   r   rD   r	   )rF   r   )r0   r   rG   r<   r	   r   r   r   
get_statusL  s    

zPyErg.get_statusc             C   sF   t j  }d|j|j|jg}|d|jd |j|jg | 	| dS )zK
        Sets the erg clock to the computers current time and date
        ZCSAFE_SETTIME_CMDZCSAFE_SETDATE_CMDil  N)
r-   r.   hourminutesecondrE   yearmonthdayrF   )r0   r.   rG   r   r   r   	set_clockY  s    
zPyErg.set_clockNc             C   s|  |  dg g }|dkr*| |ddd n|dkrt|dkrJ|dd t|dkrb|dd | |d ddd	 | |d d
dd | |d ddd |d dkr|d dkr|d dk rtd|d|d |d |d g n*|dkr| |ddd |d|dg |dk	r|dk	r|dkrt|d }|d d |d d  |d  }	t|	d d d }
| |dtd|
|	d  |dd|g nT|dk	r|dkrt|d d }
| |dtd|
| |dd|g ntd|dk	rttd|d  d!  }n|dk	r4tt|d" d# }|dk	rN|d$|d%g |dkr\d}|d&|dd'g |  | dS )(a  
        If machine is in the ready state, function will set the
        workout and display the start workout screen
        Choose one of:
        program: workout program 0 to 15
        workout_time: workout time as a list, [hours, minutes, seconds]
        distance: meters
        If workout_time or distance, optional: split
        One of the following for pace boat (optional):
        pace: seconds
        calpace: calories per hour
        powerpace: watts
        ZCSAFE_RESET_CMDNZProgramr   rD   r#   rB   z
Time Hours	   zTime Minutes;   zTime Seconds   zWorkout too shortZCSAFE_SETTWORK_CMDr   d   iP  ZCSAFE_SETHORIZONTAL_CMD$   i  <      g      ?z
Split Timei  ZCSAFE_PM_SET_SPLITDURATIONzSplit distance   z!Cannot set split for current goalgffffff@g     @@rN   g     r@gOe@ZCSAFE_SETPOWER_CMDX   ZCSAFE_SETPROGRAM_CMDZCSAFE_GOINUSE_CMD)	rF   r4   leninsertr   rE   r   maxround)r0   ZprogramZworkout_timer@   splitrA   ZcalpaceZ	powerpacerG   Ztime_rawZminsplitr   r   r   set_workoutd  sR    $

 



zPyErg.set_workoutc       
   
   C   s  t j  }|| j }|j|jd  }|tk r:tt|  t	|}y| j
j	| j|dd}W n4 tk
r } z|jdkrtdW dd}~X Y nX t j  | _g }xn|sy"| j
j| j|dd}	t|	}W q tk
r } z t|	 t| t| |W dd}~X Y qX qW |S )zb
        Converts and sends message to erg; receives, converts, and returns ergs response
        g    .Ai  )timeout   zUSB device disconectedN)r-   r.   r/   secondsmicrosecondsMIN_FRAME_GAPr?   sleepr   writer*   r,   r   r   ConnectionErrorreadr+   	Exceptionprint)
r0   messager.   deltaZdeltarawZcsafelengthr   ZresponseZtransmissionr   r   r   rF     s.    



z
PyErg.send)FF)F)F)F)F)NNNNNNN)__name__
__module____qualname____doc__r1   staticmethodr4   rI   rJ   rM   rQ   rR   rY   rh   rF   r   r   r   r   r       s   &
K



  
Kr    )rz   r-   r?   r%   Zusb.corer   Zusb.utilr   Zpyrow.csafer   r   rm   r'   r   r   r   r   objectr    r   r   r   r   <module>   s   

