Xcom_Test_Loop_Program.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. ##########################################################################################################################################
  4. # Python-File Information #
  5. ##########################################################################################################################################
  6. #
  7. # File: Xcom_Test_Program.py
  8. # Author: Tobias Müller
  9. # Date: 2017.08.09
  10. #
  11. ##########################################################################################################################################
  12. # Requirements #
  13. ##########################################################################################################################################
  14. import sys
  15. import signal
  16. import socket
  17. import os
  18. import time
  19. import ptvsd as debug
  20. import serial as UART
  21. import pigpio as GPIO
  22. from Xcom_API import Xcom_API
  23. ##########################################################################################################################################
  24. # Class Definition & Description #
  25. ##########################################################################################################################################
  26. # This program demonstrate the functionality of the Xcom_API-class. It sends permanently a request for a known object_id and display
  27. # it. To use this program a Raspberry Pi with a Raspicomm extender module and a RS232-bridge called Xcom-232i is required.
  28. ##########################################################################################################################################
  29. # Program Information #
  30. ##########################################################################################################################################
  31. PROG_NAME = 'Xcom_Test_Program'
  32. PROG_VERSION = 'v1.0'
  33. ##########################################################################################################################################
  34. # Debug server-Settings #
  35. ##########################################################################################################################################
  36. debug.enable_attach(secret='Debug')
  37. ##########################################################################################################################################
  38. # GPIO-Server-Setting #
  39. ##########################################################################################################################################
  40. # LED-Ports
  41. LED1 = 18
  42. LED2 = 27
  43. # Detect GPIO-HOST
  44. Hostname = socket.gethostname()
  45. # GPIO-State-Variable
  46. GPIO_ENABLE = False
  47. # GPIO-ERROR_Variable
  48. GPIO_ERR = False
  49. ##########################################################################################################################################
  50. # COM-Port-Setting #
  51. ##########################################################################################################################################
  52. # COM-Parameter-Variable
  53. COM_PARA = {'Port' : '/dev/ttyAMA0',
  54. 'Baudrate' : 115200,
  55. 'Bytesize' : UART.EIGHTBITS,
  56. 'Parity' : UART.PARITY_EVEN,
  57. 'Stopbits' : UART.STOPBITS_ONE,
  58. 'Timeout' : 2,
  59. 'XON_XOFF' : False,
  60. 'RTS_CTS' : False,
  61. 'DSR_DTR' : False}
  62. # COM-State-Variable
  63. COM_ENABLE = False
  64. # COM-ERROR-Variable
  65. COM_ERR = False
  66. COM_TIME_ERR = False
  67. ##########################################################################################################################################
  68. # Global Variable #
  69. ##########################################################################################################################################
  70. object_set = False
  71. port = ''
  72. baudrate = ''
  73. crc = False
  74. source = ''
  75. destination = ''
  76. ##########################################################################################################################################
  77. # Functions #
  78. ##########################################################################################################################################
  79. # exit Programm
  80. def exit():
  81. sys.exit(0)
  82. #print header
  83. def header():
  84. # Use Global-Variable
  85. global port
  86. global baudrate
  87. global object_set
  88. global PROG_NAME
  89. global PROG_VERSION
  90. global COM_ENABLE
  91. global GPIO_ENABLE
  92. global destination
  93. global crc
  94. global source
  95. # clear terminal
  96. os.system('cls' if os.name == 'nt' else 'clear')
  97. #print Header
  98. print('#' *120)
  99. print('#' *120)
  100. print('##',' ' *114,'##')
  101. print('## Welcome to {} version: {}. This program demonstrate the functionality of the {}-class. ##'.format(PROG_NAME, PROG_VERSION[1:],Xcom_API.get_prog_name()))
  102. print('## It sends permanently a request for a known object_id and display it.',' ' *42,'##')
  103. print('##',' ' *114,'##')
  104. print('## COM-Port: {}{}destination-addr.: {}{}Version Xcom_API: {} ##'.format(port,' '*(26-len(port)),destination,' '*(24-len(destination)),Xcom_API.get_prog_version()[1:]))
  105. print('## Baudrate: {}{}source-addr.: {}{}Object of Xcom_API set: {}{} ##'.format(baudrate,' '*(26-len(baudrate)),source,' '*(29-len(source)),object_set,' '*(object_set)))
  106. print('## COM enable: {}{}CRC-Check enable: {}{}GPIO enable: {}{} ##'.format(COM_ENABLE,' '*(19+COM_ENABLE),crc,' '*(20+crc),GPIO_ENABLE,' '*(GPIO_ENABLE)))
  107. print('##',' ' *114,'##')
  108. print('#' *120)
  109. print('#' *120,'\n')
  110. # setup
  111. def setup():
  112. # Use Global-Variable
  113. global COM_PARA
  114. global port
  115. global baudrate
  116. global destination
  117. global crc
  118. global source
  119. # get COM-Port
  120. if len(sys.argv) >= 2:
  121. port = sys.argv[1]
  122. COM_PARA['Port'] = port
  123. header()
  124. else:
  125. while True:
  126. Buffer = input('Do you want to use COM-Port: /dev/ttyAMA0? (yes/no): ')
  127. if Buffer == 'yes' or Buffer == 'y':
  128. port = COM_PARA['Port']
  129. header()
  130. break
  131. elif Buffer == 'no' or Buffer == 'n':
  132. port = input('Enter a COM-Port: ')
  133. COM_PARA['Port'] = port
  134. header()
  135. break
  136. else:
  137. print('What do you mean?\n')
  138. # get baudrate
  139. if len(sys.argv) >= 3 and (sys.argv[2] == '115200' or sys.argv[2] == '38400'):
  140. baudrate = sys.argv[2]
  141. COM_PARA['Baudrate'] = int(baudrate)
  142. header()
  143. else:
  144. while True:
  145. Buffer = input('Do you want to use a Baudrate of: 115200? (yes/no): ')
  146. if Buffer == 'yes' or Buffer == 'y':
  147. baudrate = str(COM_PARA['Baudrate'])
  148. header()
  149. break
  150. elif Buffer == 'no' or Buffer == 'n':
  151. while True:
  152. baudrate = input('Enter a Baudrate (115200 or 38400): ')
  153. if baudrate == '115200' or baudrate == '38400':
  154. COM_PARA['Baudrate'] = int(baudrate)
  155. header()
  156. break
  157. else:
  158. print('baudrate: {}, is not supported.'.format(baudrate))
  159. break
  160. else:
  161. print('What do you mean?\n')
  162. # get destination-address
  163. if len(sys.argv) >= 4:
  164. destination = sys.argv[3]
  165. header()
  166. else:
  167. while True:
  168. Buffer = input('Do you want to use the destination-address: 101? (yes/no): ')
  169. if Buffer == 'yes' or Buffer == 'y':
  170. destination = str(101)
  171. header()
  172. break
  173. elif Buffer == 'no' or Buffer == 'n':
  174. while True:
  175. destination = input('Enter a destination-address: ')
  176. try:
  177. if isinstance(int(destination),int):
  178. header()
  179. break
  180. except ValueError:
  181. print('destination-address: {}, is not an integer.'.format(destination))
  182. break
  183. else:
  184. print('What do you mean?\n')
  185. # get source-address
  186. if len(sys.argv) >= 5:
  187. source = sys.argv[4]
  188. header()
  189. else:
  190. while True:
  191. Buffer = input('Do you want to use the source-address: 1? (yes/no): ')
  192. if Buffer == 'yes' or Buffer == 'y':
  193. source = str(1)
  194. header()
  195. break
  196. elif Buffer == 'no' or Buffer == 'n':
  197. while True:
  198. source = input('Enter a source-address: ')
  199. try:
  200. if isinstance(int(source),int):
  201. header()
  202. break
  203. except ValueError:
  204. print('source-address: {}, is not an integer.'.format(source))
  205. break
  206. else:
  207. print('What do you mean?\n')
  208. # get crc check state
  209. if len(sys.argv) == 6 and (sys.argv[5] == 'False' or sys.argv[5] == 'True' or sys.argv[5] == '1' or sys.argv[5] == '0'):
  210. if sys.argv[5] == 'True' or sys.argv[5] == '1':
  211. crc = True
  212. else:
  213. crc = False
  214. header()
  215. else:
  216. while True:
  217. Buffer = input('Do you want to activate CRC-Check? (yes/no): ')
  218. if Buffer == 'yes' or Buffer == 'y':
  219. crc = True
  220. header()
  221. break
  222. elif Buffer == 'no' or Buffer == 'n':
  223. crc = False
  224. header()
  225. break
  226. else:
  227. print('What do you mean?\n')
  228. # open GPIOs
  229. def open_gpios(LED1,LED2,Hostname):
  230. # Use Global-Variable
  231. global GPIO_ERR
  232. global GPIO_ENABLE
  233. # Try Function
  234. try:
  235. # Enable GPIO-Server
  236. LED_Handle = GPIO.pi(Hostname)
  237. # GPIO-Mode
  238. LED_Handle.set_mode(LED1, GPIO.OUTPUT)
  239. LED_Handle.set_mode(LED2, GPIO.OUTPUT)
  240. # GPIO-Start-State
  241. LED_Handle.write(LED1, GPIO.LOW)
  242. LED_Handle.write(LED2, GPIO.LOW)
  243. GPIO_ENABLE = True
  244. # print completed task
  245. print('GPIOs on \"{}\" are configured.'.format(Hostname))
  246. # return LED-Handle
  247. return LED_Handle
  248. # Handle Errors
  249. except AttributeError:
  250. print('There is no connection to the \"{}\" possible.\nEnsure that the Deamon-Host-Process\"pigpiod\" has started with root privileges on the Raspberry Pi to connect to the GPIOs.'.format(Hostname))
  251. GPIO_ERR = True
  252. exit()
  253. # close GPIOs
  254. def close_gpios(LED_Handle,Hostname,LED1,LED2):
  255. # Use Global-Variable
  256. global GPIO_ERR
  257. global GPIO_ENABLE
  258. # Try Function
  259. try:
  260. # Reset GPIOs
  261. LED_Handle.clear_bank_1(1<<LED1)
  262. LED_Handle.clear_bank_1(1<<LED2)
  263. # close GPIO-Server
  264. LED_Handle.stop()
  265. GPIO_ENABLE = False
  266. # print completed task
  267. print('GPIOs closed.')
  268. except AttributeError:
  269. print('There is no connection to the \"{}\" possible.\n GPIOs can not be closed safely.'.format(Hostname))
  270. GPIO_ERR = True
  271. exit()
  272. # open COM-Port
  273. def open_com_port(LED_Handle,LED1,COM_PARA):
  274. # Use Global-Variable
  275. global COM_ENABLE
  276. global COM_ERR
  277. # Try Function
  278. try:
  279. # open COM-Port
  280. COM_Handle = UART.Serial(port = COM_PARA['Port'],
  281. baudrate = COM_PARA['Baudrate'],
  282. bytesize = COM_PARA['Bytesize'],
  283. parity = COM_PARA['Parity'],
  284. stopbits = COM_PARA['Stopbits'],
  285. timeout = COM_PARA['Timeout'],
  286. xonxoff = COM_PARA['XON_XOFF'],
  287. rtscts = COM_PARA['RTS_CTS'],
  288. dsrdtr = COM_PARA['DSR_DTR'])
  289. COM_ENABLE = True
  290. # LED1 on
  291. LED_Handle.write(LED1, GPIO.HIGH)
  292. # print completed task
  293. print('COM-Port: \"{}\", is opened.'.format(COM_Handle.port))
  294. # return COM_Handle
  295. return COM_Handle
  296. # Handle Errors
  297. except UART.SerialException:
  298. print('COM-Port: \"{}\", can not be opened. Make sure it is available and not used by other programs.'.format(COM_PARA['Port']))
  299. COM_ERR = True
  300. exit()
  301. except ValueError:
  302. print('COM-Port-Parameters are out of spezifications.')
  303. COM_ERR = True
  304. exit()
  305. except TypeError:
  306. print('Baudrate: {}, is not supported.'.format(COM_PARA['Baudrate']))
  307. COM_ERR = True
  308. exit()
  309. # close COM-Port
  310. def close_com_port(COM_Handle,LED_Handle,LED1):
  311. # Use Global-Variable
  312. global COM_ENABLE
  313. global COM_ERR
  314. # Try Function
  315. try:
  316. # save Port-Name
  317. port = COM_Handle.port
  318. # close COM-Port
  319. COM_Handle.close()
  320. COM_ENABLE = False
  321. # LED1 off
  322. LED_Handle.write(LED1, GPIO.LOW)
  323. # print completed task
  324. print('COM-Port: \"{}\", is closed.'.format(port))
  325. # Handle Errors
  326. except UART.SerialException:
  327. print('COM-Port: \"{}\", can not be closed.'.format(port))
  328. COM_ERR = True
  329. exit()
  330. # write to COM-Port
  331. def com_wite(LED_Handle,LED2,COM_Handle,BUFFER):
  332. # LED2 on
  333. LED_Handle.write(LED2, GPIO.HIGH)
  334. # sent Byte-Frame
  335. COM_Handle.write(BUFFER)
  336. # LED2 off
  337. LED_Handle.write(LED2, GPIO.LOW)
  338. # read from COM-Port
  339. def com_read(LED_Handle,LED2,COM_Handle):
  340. # LED2 on
  341. LED_Handle.write(LED2, GPIO.HIGH)
  342. # read Byteframe
  343. BUFFER = COM_Handle.read(30)
  344. # LED2 off
  345. LED_Handle.write(LED2, GPIO.LOW)
  346. # return Buffer
  347. return BUFFER
  348. # Create object of class Xcom_API
  349. def create_obj_of_class(destination,source,crc):
  350. # Use Global-Variable
  351. global object_set
  352. #Try Function
  353. try:
  354. # Create an object of class Xcom_API
  355. OBJ_Handle = Xcom_API(crc=crc,destination=int(destination),source=int(source))
  356. object_set = True
  357. return OBJ_Handle
  358. # Handle Errors
  359. except:
  360. print('Destination- and/or source-address are not supported.')
  361. exit()
  362. ##########################################################################################################################################
  363. # Main-Program #
  364. ##########################################################################################################################################
  365. # Try Main-Function
  366. try:
  367. # print Header
  368. header()
  369. # run setup if to check arguments an create an object of the class Xcom_API
  370. setup()
  371. # Configure GPIOs and COM-Port and object of class
  372. LED_Handle = open_gpios(LED1,LED2,Hostname)
  373. header()
  374. COM_Handle = open_com_port(LED_Handle,LED1,COM_PARA)
  375. header()
  376. OBJ_Handle = create_obj_of_class(destination,source,crc)
  377. header()
  378. #Ask for Object_ID create Frame for request
  379. while True:
  380. try:
  381. header()
  382. print('Known Parameter-Numbers (object_id):')
  383. print(' maximum current of ac source = 1107\n battery charge current = 1138\n smart boost allowed = 1126')
  384. print(' inverter allowed = 1124\n type of detection of grid loss = 1552\n charger allowed = 1125')
  385. print(' charger uses only power from ac = 1646\n ac output voltage = 1286\n inverter frequency = 1112')
  386. print(' transfer relay allowed = 1128\n limitation of the power boost = 1607\n remote entry active = 1545')
  387. print('\nKnown Information-Numbers (object_id):')
  388. print(' battery voltage = 3000\n battery charge current = 3005\n battery temperature = 3001')
  389. print(' battery voltage ripple = 3006\n state of charge = 3007\n number of battery elements = 3050')
  390. print(' input voltage = 3011\n input current = 3012\n input frequency = 3084')
  391. print(' input power = 3138\n output voltage = 3021\n output current = 3022')
  392. print(' output frequency = 3085\n output power = 3139\n operating state = 3028')
  393. print(' boost active = 3019\n state of inverter = 3049\n state of transfer relay = 3020')
  394. print(' state of output relay = 3030\n state of aux relay 1 = 3031\n state of aux relay 2 = 3032')
  395. print(' state of ground relay = 3074\n state of neutral transfer relay = 3075\n state of remote entry = 3086')
  396. Buffer = int(input('\nType in an object_id: '))
  397. Buffer = OBJ_Handle.get_read_frame(Buffer)
  398. header()
  399. break
  400. except:
  401. while True:
  402. Buffer = input('\nobject_id unknown, do you want to try it again (yes/no): ')
  403. if Buffer == 'yes' or Buffer == 'y':
  404. header()
  405. break
  406. elif Buffer == 'no' or Buffer =='n':
  407. header()
  408. exit()
  409. else:
  410. print('\nWhat do you mean?')
  411. # main while loop:
  412. while True:
  413. # send Byteframe
  414. com_wite(LED_Handle,LED2,COM_Handle,Buffer)
  415. # read from COM-Port
  416. Buffer2 = com_read(LED_Handle,LED2,COM_Handle)
  417. # get data from frame print value
  418. Buffer2 = OBJ_Handle.get_data_from_frame(Buffer2)
  419. if not Buffer2[0]:
  420. print('Answer from xtender:',Buffer2[1])
  421. else:
  422. print('Answer from xtender:',OBJ_Handle.get_text_from_error_id(Buffer2[1]))
  423. # Handle Errors
  424. except KeyboardInterrupt:
  425. if signal.SIGINT:
  426. print('\n\nProgram closed with Strg+c.')
  427. # Exit program safely.
  428. finally:
  429. print('\nExit Program.')
  430. if (('COM_Handle' in locals() and COM_Handle and COM_ENABLE and not COM_ERR) or
  431. ('LED_Handle' in locals() and LED_Handle and GPIO_ENABLE and not GPIO_ERR)):
  432. print('\nCleanup work:')
  433. if 'COM_Handle' in locals() and COM_Handle and COM_ENABLE and not COM_ERR:
  434. close_com_port(COM_Handle,LED_Handle,LED1)
  435. if 'LED_Handle' in locals() and LED_Handle and GPIO_ENABLE and not GPIO_ERR:
  436. close_gpios(LED_Handle,Hostname,LED1,LED2)