Coverage for pyilper/pilbox.py: 86%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

84 statements  

1#!/usr/bin/python3 

2# -*- coding: utf-8 -*- 

3# pyILPER 1.2.1 for Linux 

4# 

5# An emulator for virtual HP-IL devices for the PIL-Box 

6# derived from ILPER 1.4.5 for Windows 

7# Copyright (c) 2008-2013 Jean-Francois Garnier 

8# C++ version (c) 2013 Christoph Gießelink 

9# Python Version (c) 2015 Joachim Siebold 

10# 

11# This program is free software; you can redistribute it and/or 

12# modify it under the terms of the GNU General Public License 

13# as published by the Free Software Foundation; either version 2 

14# of the License, or (at your option) any later version. 

15# 

16# This program is distributed in the hope that it will be useful, 

17# but WITHOUT ANY WARRANTY; without even the implied warranty of 

18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

19# GNU General Public License for more details. 

20# 

21# You should have received a copy of the GNU General Public License 

22# along with this program; if not, write to the Free Software 

23# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 

24# 

25# PIL-Box object class --------------------------------------------- 

26# 

27# Initial version derived from ILPER 1.43 

28# 

29# Changelog 

30# 

31# 09.02.2014 improvements and changes of ILPER 1.45 

32# - send RFC to virtual devices after each cmd frame 

33# - high byte detection 

34# 

35# 07.06.2014 jsi 

36# - introduce configurable baudrate support 

37# 06.10.2015 jsi: 

38# - class statement syntax update 

39# 16.10.2015 jsi: 

40# - removed SSRQ, CSRQ approach 

41# - introduced COFI switch to get real IDY frames from the loop (requires firmware 1.6) 

42# 29.11.2015 jsi: 

43# - removed activity timer 

44# 30.11.2015 jsi: 

45# - introduced idyframe option 

46# 03.02.2015 jsi 

47# - set frame timeout to 50 msec 

48# 07.02.2015 jsi 

49# - set pilbox call removed 

50# 22.02.2016 cg 

51# - send the cmd and not the RFC frame back to the PIL-Box 

52# 22.03.2016 cg 

53# - send acknowledge for high byte only at a 9600 baud connection 

54# 26.04.2016 jsi 

55# - auto baudrate support, code taken from cgi 

56# 09.05.2016 jsi 

57# - reenable baud rate setting in addition to auto baud support 

58# 11.07.2016 jsi 

59# - autobaud detection rewritten, hint by cg 

60# - move constants to pilcore.py 

61# 13.10.2016 jsi 

62# - remove unregister function 

63# - store tab name if device is registered 

64# 30.10.2016 jsi 

65# - getDevices added (removed by mistake) 

66# 07.10.2017 jsi 

67# - refactoring: moved process(), sendFrame() and device list handling code to 

68# thread object 

69# 

70# PIL-Box Commands 

71# 

72COFF= 0x497 # initialize in controller off mode 

73TDIS= 0x494 # disconnect 

74COFI= 0x495 # switch PIL-Box to transmit real IDY frames 

75 

76from .pilrs232 import Rs232Error, cls_rs232 

77from .pilcore import * 

78 

79class PilBoxError(Exception): 

80 def __init__(self,msg,add_msg=None): 

81 self.msg=msg 

82 if add_msg is None: 

83 self.add_msg="" 

84 else: 

85 self.add_msg= add_msg 

86 

87 

88class cls_pilbox: 

89 

90 def __init__(self,ttydevice,baudrate,idyframe): 

91 self.__baudrate__= baudrate # baudrate of connection or 0 for autodetect 

92 self.__idyframe__= idyframe # switch box to send idy frames 

93 self.__tty__= cls_rs232() # serial device object 

94 self.__ttydevice__=ttydevice # serial port name 

95 

96# 

97# get connection speed 

98# 

99 def getBaudRate(self): 

100 return(self.__baudrate__) 

101# 

102# send command to PIL-Box, check return value 

103# 

104 def __sendCmd__(self,cmdfrm,tmout): 

105 hbyt,lbyt= disassemble_frame(cmdfrm) 

106 try: 

107 self.write(lbyt,hbyt) 

108 bytrx= self.__tty__.rcv(tmout) 

109 except Rs232Error as e: 

110 raise PilBoxError("PIL-Box command error:", e.value) 

111 if bytrx is None: 

112 raise PilBoxError("PIL-Box command error: timeout","") 

113 try: 

114 if ((ord(bytrx) & 0x3F) != (cmdfrm & 0x3F)): 

115 raise PilBoxError("PIL-Box command error: illegal retval","") 

116 except TypeError: 

117 raise PilBoxError("PIL-Box command error: illegal retval","") 

118 

119# 

120# Connect to PIL-Box in controller off mode 

121# 

122 def open(self): 

123# 

124# open serial device, no autobaud mode 

125# 

126 if self.__baudrate__ > 0: 

127 try: 

128 self.__tty__.open(self.__ttydevice__, self.__baudrate__) 

129 except Rs232Error as e: 

130 raise PilBoxError("Cannot connect to PIL-Box", e.value) 

131 self.__sendCmd__(COFF,TMOUTCMD) 

132 

133 else: 

134# 

135# open serial device, detect baud rate, use predefined baudrates in 

136# BAUDRATES list in reverse order 

137# 

138 success= False 

139 errmsg="" 

140 for i in range(len(BAUDRATES)-1,0,-1): 

141# 

142# open device at the beginning of the loop, if error throw exception and exit 

143# 

144 baudrate= BAUDRATES[i][1] 

145 if i== len(BAUDRATES)-1: 

146 try: 

147 self.__tty__.open(self.__ttydevice__, baudrate) 

148 except Rs232Error as e: 

149 raise PilBoxError("Cannot connect to PIL-Box", e.value) 

150# 

151# otherwise reset device and use next baudrate 

152# 

153 else: 

154 try: 

155 self.__tty__.flushInput() 

156 self.__tty__.setBaudrate(baudrate) 

157 except Rs232Error as e: 

158 raise PilBoxError("Cannot connect to PIL-Box", e.value) 

159# 

160# initialize PIL-Box with current baud rates 

161# 

162 try: 

163 self.__sendCmd__(COFF,TMOUTCMD) 

164 success= True 

165 self.__baudrate__=baudrate 

166 break 

167 except PilBoxError as e: 

168 errmsg=e.msg 

169# 

170# no success with any baud rate, throw exception and exit 

171# 

172 if not success: 

173 self.__tty__.close() 

174 raise PilBoxError("Cannot connect to PIL-Box", errmsg) 

175 

176 if self.__idyframe__: 

177 self.__sendCmd__(COFI,TMOUTCMD) 

178 

179# 

180# Disconnect PIL-Box 

181# 

182 def close(self): 

183 try: 

184 self.__sendCmd__(TDIS,TMOUTCMD) 

185 finally: 

186 self.__tty__.close() 

187# 

188# Read byte from PIL-Box 

189# 

190 def read(self): 

191 try: 

192 bytrx= self.__tty__.rcv(TMOUTFRM) 

193 except Rs232Error as e: 

194 raise PilBoxError("PIL-Box read frame error", e.value) 

195 return bytrx 

196# 

197# Send one or two bytes to the PIL-Box 

198# 

199 def write(self,lbyt,hbyt=None): 

200 if hbyt is None: 

201 buf=bytearray([lbyt]) 

202 else: 

203 buf=bytearray([hbyt,lbyt]) 

204 try: 

205 self.__tty__.snd(buf) 

206 except Rs232Error as e: 

207 raise PilBoxError("PIL-Box send frame error", e.value)