def get_prgm_name(self, N):
     reg = 16886 + (N - 1) * 40
     self.__range_check(N, 1, 40)
     if not self.profiles:
         raise ControllerInterfaceError(
             "This watlow does not impliment profiles")
     return self.client.read_holding_string(reg, 20)
 def prgm_delete(self, N):
     self.__range_check(N, 1, 40)
     if not self.profiles:
         raise ControllerInterfaceError(
             "This watlow does not impliment profiles")
     try:
         self.client.write_holding(18888, N)  #set active profile
         self.client.write_holding(
             18890, self.inv_watlow_val_dict('delete'))  #delete profile
     except ModbusError, exp:
         exp.message = 'Cannot delete program. (original message: %s)' % exp.message
         raise  # something else went wrong pass the exception on up.
 def prgm_start(self, N, step):
     self.__range_check(N, 1, 40)
     if step > self.get_prgm_steps(N, exclusive=False):
         raise ControllerInterfaceError(
             "Program #%d does not have step #%d." % (N, step))
     if self.get_status(exclusive=False).find("Program") >= 0:
         self.client.write_holding(16566,
                                   self.inv_watlow_val_dict('terminate'))
         time.sleep(2)
     self.client.write_holding(16558, N)  #profile to start
     self.client.write_holding(16560, step)  #step to start
     self.client.write_holding(
         16562, self.inv_watlow_val_dict('start'))  #start the profile
 def __profile_units(self, num):
     '''
     Get the units for the profile loops pv/sp
     '''
     if not self.profiles:
         raise ControllerInterfaceError(
             "Profile support is required to read units.")
     reg = 16536 + (num - 1) * 2
     profpv = self.client.read_holding(reg, 1)[0]
     try:
         tlist = [
             'absoluteTemperature', 'relativeTemperature', 'notsourced'
         ]
         if self.watlow_val_dict[profpv] in tlist:
             tval = self.client.read_holding(
                 14080 if self.interface == "RTU" else 6730, 1)[0]
             return u'\xb0%s' % self.watlow_val_dict[tval]
         else:
             return u'%s' % self.watlow_val_dict[profpv]
     except LookupError:
         return u'ERROR'
 def get_prgm(self, N):
     if N == 0:
         return self.__get_prgm_empty()
     rbase = 4003 #first register to read
     self.__range_check(N, 1, 40)
     self.client.write_holding(4000, N)
     program = {
         'steps':[],
         'name': self.get_prgm_name(N, exclusive=False),
         'steps_available': self.client.read_holding(1219)[0]
     }
     daylookup = ['daily', 'sun', 'mon', 'tue', 'wed', 'thur', 'fri', 'sat']
     dins = [self.client.read_holding(1060+i*2)[0] == 10 for i in range(4)]
     analogs = self.__get_analog_input_setup()
     for step in range(1, 257):
         self.client.write_holding(4001, step)
         params = self.client.read_holding_signed(rbase, 4062-rbase+1) #registers 4003-4062
         step_params = {
             'type':'soak',
             'start_type':'day',
             'start_date':{'month':1, 'day':1, 'year':2000},
             'start_time':{'day':'sunday', 'hours':0, 'minutes':0, 'seconds':0},
             'loops':[
                 {
                     'enable':True,
                     'target':0,
                     'pidset':1 + 5*i,
                     'gsoak':False,
                     'isCascade': self.cascades > 0 if i == 0 else False,
                     'showEnable': self.combined_event[i] > 0
                 }
                 for i in range(self.loops + self.cascades)
             ],
             'events':[
                 {'number':i, 'value':'off'}
                 for i in range(1, 9) if i not in self.combined_event and i != self.cond_event
             ],
             'wait':{
                 'enable':False,
                 'digital':[
                     {'number':i+1, 'enable':False, 'value':'off'}
                     for i in range(4) if dins[i]
                 ],
                 'analog':[
                     {'number':i+1, 'enable':False, 'value':0.0}
                     for i in range(len(analogs)) if analogs[i] != 'off'
                 ]
             },
             'duration':{'hours':0, 'minutes':0, 'seconds':0},
             'jprofile':0,
             'jstep':0,
             'jcount':0,
             'action':'hold'
         }
         if self.loops + self.cascades == 1:
             step_params['loops'][0]['rate'] = 0
         if params[4003-rbase] == 0:#Auto start
             step_params.update({
                 'type':'autostart',
                 'start_type':['date', 'day'][params[4004-rbase]],
                 'start_date':{
                     'month':params[4005-rbase],
                     'day':params[4006-rbase],
                     'year':params[4007-rbase]
                 },
                 'start_time':{
                     'day':daylookup[params[4008-rbase]],
                     'hours':params[4009-rbase],
                     'minutes':params[4010-rbase],
                     'seconds':params[4011-rbase]
                 }
             })
         elif params[4003-rbase] in [1, 2, 3]: #ramptime, ramprate, soak
             step_params.update({
                 'type': ['', 'ramptime', 'ramprate', 'soak'][params[4003-rbase]],
                 'wait':{'enable': params[4012-rbase] == 1},
                 'events':[
                     {'number':i, 'value':'on' if params[4030-rbase-1+i] else 'off'}
                     for i in range(1, 9) if i not in self.combined_event and i != self.cond_event
                 ],
                 'loops':[
                     {
                         'enable':params[4030-rbase-1+self.combined_event[i]] == 1 \
                                     if self.combined_event[i] else True,
                         'target':params[4044-rbase+i] * self.__get_scalar(i+1),
                         'pidset':params[4046-rbase+i] + 1 + 5*i,
                         'gsoak':params[4048-rbase+i] == 1,
                         'isCascade': self.cascades > 0 if i == 0 else False,
                         'showEnable': self.combined_event[i] > 0
                     }
                     for i in range(self.loops + self.cascades)
                 ]
             })
             if self.loops + self.cascades == 1:
                 step_params['loops'][0]['rate'] = 0
             if params[4003-rbase] != 2:
                 step_params['duration'] = {
                     'hours':params[4009-rbase],
                     'minutes':params[4010-rbase],
                     'seconds':params[4011-rbase]
                 }
             else:
                 step_params['loops'][0]['rate'] = params[4043-rbase] / 10.0
             step_params['wait'].update({
                 'digital':[
                     {
                         'number':i+1,
                         'enable':params[4013-rbase+i] != 0,
                         'value':['off', 'off', 'on'][params[4013-rbase+i]]
                     }
                     for i in range(4) if dins[i]
                 ],
                 'analog':[
                     {
                         'number':i+1,
                         'enable':params[4021-rbase+i*2] == 1,
                         'value':params[4022-rbase+i*2] * self.__get_scalar(i+1)
                     }
                     for i in range(len(analogs)) if analogs[i] != 'off'
                 ]
             })
         elif params[4003-rbase] == 4:#Jump
             #if we are jumping to the same profile hprofile will be 0
             prof_num = params[4050-rbase]
             prof_num = 0 if prof_num == N else prof_num
             step_params.update({
                 'type':'jump',
                 'jprofile':prof_num,
                 'jstep':params[4051-rbase],
                 'jcount':params[4052-rbase]
             })
         elif params[4003-rbase] == 5:#End
             step_params.update({
                 'type':'end',
                 'action':['hold', 'controloff', 'alloff', 'idle'][params[4060-rbase]],
                 'loops':[
                     {
                         'enable':True,
                         'target':params[4061-rbase+i]*self.__get_scalar(i+1),
                         'pidset':1 + 5*i,
                         'gsoak':False,
                         'isCascade': self.cascades > 0 if i == 0 else False,
                         'showEnable': self.combined_event[i] > 0
                     }
                     for i in range(self.loops + self.cascades)
                 ]
             })
             if self.loops + self.cascades == 1:
                 step_params['loops'][0]['rate'] = 0
         else:#Not a program
             raise ControllerInterfaceError('Program #%d does not exist' % N)
         program['steps'].append(step_params)
         if step_params['type'] == 'end':
             break
     return program
Beispiel #6
0
 def get_prgm(self, N):
     try:
         return self.client.read_prgm(N, self.cascades > 0)
     except EspecError:
         raise ControllerInterfaceError(
             'Could not read program from chamber controller.')
    def get_prgm(self, N):
        def event_mod(vals, event):
            '''Get event from events/gs register block'''
            event -= 1
            if event < 4:
                return self.watlow_val_dict[vals[8 + event * 2]]
            else:
                return self.watlow_val_dict[vals[24 + (event - 4) * 2]]

        if N == 0:
            return self.__get_prgm_empty()
        self.__range_check(N, 1, 40)
        if not self.profiles:
            raise ControllerInterfaceError(
                "This watlow does not impliment profiles")
        self.client.write_holding(18888, N)  #set active profile
        step_count = self.client.read_holding(
            18920, 1)[0]  #get the number of steps in the profile
        if not step_count > 0:
            raise ControllerInterfaceError("Profile %d does not exist." % N)
        prgm_dict = {
            'name': self.client.read_holding_string(18606, 20),
            'log': self.client.read_holding(19038, 1)[0] == 106
        }
        #is wait a valid step type
        haswaits = self.waits[0] != '' or self.waits[1] != ''
        haswaits = haswaits or self.waits[2] != '' or self.waits[3] != ''
        prgm_dict['haswaits'] = haswaits
        prgm_dict['hasenables'] = sum(self.loop_event + self.cascade_event) > 0
        ranges, gsd, steps = [], [], []
        for i in range(self.loops + self.cascades):
            tmap = self.loop_map[i]
            gsd.append(
                {'value': self.client.read_holding_float(19086 + i * 2)[0]})
            if tmap['type'] == 'loop':
                ranges.append(self.get_loop_range(tmap['num'],
                                                  exclusive=False))
            else:
                ranges.append(
                    self.get_cascade_range(tmap['num'], exclusive=False))
        for i in range(step_count):
            ldata, wdata = [], []
            step_type = self.watlow_val_dict[self.client.read_holding(
                19094 + 170 * i, 1)[0]]
            sdata = {'type': step_type}  #step type
            if step_type in ['soak', 'ramptime',
                             'instant']:  # this step has duration.
                duration = self.client.read_holding(19096 + 170 * i, 6)
                sdata['duration'] = {
                    'hours': duration[0],
                    'minutes': duration[2],
                    'seconds': duration[4]
                }
            else:
                sdata['duration'] = {'hours': 0, 'minutes': 0, 'seconds': 0}
            if step_type in ['instant', 'ramptime']:
                params = self.client.read_holding(19114 + 170 * i, 8)  #targets
            if step_type == 'ramprate':
                params = self.client.read_holding(19106 + 170 * i,
                                                  16)  #rates and targets
            if step_type == 'end':
                params = self.client.read_holding(19170 + i * 170,
                                                  7)  #endmodes

            #get all guaranteed soak enables and events
            gse_event = self.client.read_holding(19138 + 170 * i, 32)

            for j in range(self.cascades + self.loops):
                tmap = self.loop_map[j]
                if tmap['type'] == 'loop':
                    enable_event = self.loop_event[tmap['num'] - 1]
                else:
                    enable_event = self.cascade_event[tmap['num'] - 1]
                clp = ranges[j].copy()
                clp.update({
                    'mode': '',
                    'gsoak': False,
                    'target': 0.0,
                    'rate': 0.0,
                    'showEnable': False,
                    'isCascade': False,
                    'cascade': False
                })
                if step_type == 'ramprate':
                    clp['target'] = self.mod_to_float(params[8 + j * 2:10 +
                                                             j * 2])
                    clp['rate'] = self.mod_to_float(params[j * 2:2 + j * 2])
                elif step_type in ['instant', 'ramptime']:
                    clp['target'] = self.mod_to_float(params[j * 2:2 + j * 2])
                elif step_type == 'end':
                    if params[j * 2] == 100:
                        clp['mode'] = 'user'
                    elif params[j * 2] == 62:
                        clp['mode'] = 'off'
                    else:
                        clp['mode'] = 'hold'
                    clp['enable'] = True if enable_event == 0 or params[
                        j * 2] != 62 else False
                #if stepType in ['instant','ramptime','ramprate','soak']:
                clp['gsoak'] = gse_event[j * 2] == 63
                clp['showEnable'] = enable_event != 0
                clp['enable'] = True
                if enable_event != 0:
                    clp['enable'] = event_mod(gse_event, enable_event) == 'on'
                if tmap['type'] == 'cascade':
                    clp['isCascade'] = True
                    clp['cascade'] = event_mod(
                        gse_event,
                        self.cascade_ctl_event[tmap['num'] - 1]) == 'on'
                ldata.append(clp)
            sdata['loops'] = ldata
            wdraw = self.client.read_holding(19122 + i * 170, 16)
            for j in range(4):
                if self.waits[j]:
                    cwt = wdraw[j * 4]
                    cws = self.mod_to_float(wdraw[2 + j * 4:4 + j * 4])
                    wts = self.watlow_val_dict[cwt]
                    wdata.append({
                        'number': j + 1,
                        'condition': wts,
                        'value': cws
                    })
            sdata['waits'] = wdata
            jraw = self.client.read_holding(19102 + i * 170, 3)
            sdata.update({'jstep': jraw[0], 'jcount': jraw[2]})
            sdata['events'] = [{
                'number': j + 1,
                'value': event_mod(gse_event, j + 1)
            } for j in range(8)]
            steps.append(sdata)
        prgm_dict['steps'] = steps
        prgm_dict['gs_dev'] = gsd
        return prgm_dict