test1.py 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196
  1. import requests
  2. import json
  3. import ipaddress
  4. import re
  5. import aiohttp # type: ignore
  6. import asyncio
  7. # 固件信息类
  8. class Firmware:
  9. def __init__(self, model: str, sn: str, fpga: str, core: str, aux: str):
  10. self.model = model
  11. self.sn = sn
  12. self.fpga = fpga
  13. self.core = core
  14. self.aux = aux
  15. # 系统监控数据类
  16. class Monitor:
  17. def __init__(self, load_average: float, men_useage: float, uptime: float):
  18. self.load_average = load_average
  19. self.men_useage = men_useage
  20. self.uptime = uptime
  21. # 网络信息类
  22. class NetWork:
  23. def __init__(self, carrier: bool, duplex: str, ethaddr: str, hostname: str, ipv4_dhcp: bool, ipv4_addr: str, ipv4_override: str, speed: int):
  24. self.carrier = carrier
  25. self.duplex = duplex
  26. self.ethaddr = ethaddr
  27. self.hostname = hostname
  28. self.ipv4_dhcp = ipv4_dhcp
  29. self.ipv4_addr = ipv4_addr
  30. self.ipv4_override = ipv4_override
  31. self.speed = speed
  32. # 服务器数据类
  33. class OverView:
  34. def __init__(self, scanfreq: int, motor_rpm: int, laser_enable: bool, resolution: float, scan_range_start: int, scan_range_stop: int, filter_level: int, window: int, filter_min_angle: int,
  35. filter_max_angle: int, filter_neighbors: int, host_ip: str, host_port: int):
  36. self.scanfreq = scanfreq
  37. self.motor_rpm = motor_rpm
  38. self.laser_enable = laser_enable
  39. self.resolution = resolution
  40. self.scan_range_start = scan_range_start
  41. self.scan_range_stop = scan_range_stop
  42. self.filter_level = filter_level
  43. self.window = window
  44. self.filter_min_angle = filter_min_angle
  45. self.filter_max_angle = filter_max_angle
  46. self.filter_neighbors = filter_neighbors
  47. self.host_ip = host_ip
  48. self.host_port = host_port
  49. # 雷达角度扫面范围封装类
  50. class ScanRange:
  51. def __init__(self, start=None, stop=None):
  52. self.start = start
  53. self.stop = stop
  54. # 滤波器参数类
  55. class Filter:
  56. def __init__(self, level: int, window: int, min_angle: int, max_angle: int, neighbors: int):
  57. self.level = level
  58. self.window = window
  59. self.min_angle = min_angle
  60. self.max_angle = max_angle
  61. self.neighbors = neighbors
  62. # 主机配置
  63. class Host:
  64. def __init__(self, ip: str, port: int):
  65. self.ip = ip
  66. self.port = port
  67. class LakiBeamHTTP:
  68. HOST_IP_DEFAULT = "192.168.198.1"
  69. HTTP_IP_DEFAULT = "192.168.198.2"
  70. def __init__(self, local_ip: str, local_port: str, web_ip: str, web_port: str):
  71. self.local_ip = local_ip
  72. self.local_port = local_port
  73. self.web_ip = web_ip
  74. self.web_port = web_port
  75. self.base_url = "http://{}:{}".format(web_ip, web_port)
  76. self.check_ipconfig()
  77. # 获取固件信息并填充到firemware
  78. async def get_firemware(self, firemware: Firmware):
  79. goon = True
  80. try:
  81. cmdback = await self.get_async_http('/api/v1/system/firmware')
  82. document = json.loads(cmdback)
  83. if not isinstance(document, dict):
  84. return False
  85. for field in ['model', 'sn', 'fpga', 'core', 'aux']:
  86. if field in document:
  87. setattr(firemware, field, document[field])
  88. else:
  89. goon = False
  90. break
  91. return True
  92. except (requests.RequestException, json.JSONDecodeError) as e:
  93. print(f"Error fetching data: {e}")
  94. return False
  95. # 获取监控信息并填充到monitor
  96. async def get_monitor(self, monitor: Monitor):
  97. try:
  98. cmdback = await self.get_async_http('/api/v1/system/monitor')
  99. document = json.loads(cmdback)
  100. if not isinstance(document, dict):
  101. print("Error: Response is not a dictionary")
  102. return False
  103. required_fields = ['load_average', 'mem_useage', 'uptime']
  104. for field in required_fields:
  105. if field not in document:
  106. print(f"Error: Missing required field {field}")
  107. return False
  108. monitor.load_average = document['load_average']
  109. monitor.men_useage = document['mem_useage']
  110. monitor.uptime = document['uptime']
  111. return True
  112. except json.JSONDecodeError:
  113. print("Error: Failed to decode JSON")
  114. return False
  115. except aiohttp.ClientError as e:
  116. print(f"Network error: {e}")
  117. return False
  118. except Exception as e:
  119. print(f"Unexpected error: {e}")
  120. return False
  121. #从JSON数据中解析网络配置信息
  122. async def get_network(self, network: NetWork):
  123. goon = True
  124. try:
  125. cmdback = await self.get_async_http('/api/v1/system/network')
  126. document = json.loads(cmdback)
  127. if not isinstance(document, dict):
  128. return False
  129. if 'carrier' in document:
  130. network.carrier = document['carrier']
  131. else:
  132. goon = False
  133. if 'duplex' in document:
  134. network.duplex = document['duplex']
  135. else:
  136. goon = False
  137. if 'ethaddr' in document:
  138. network.ethaddr = document['ethaddr']
  139. else:
  140. goon = False
  141. if 'hostname' in document:
  142. network.hostname = document['hostname']
  143. else:
  144. goon = False
  145. if 'ipv4' in document:
  146. ipv4_info = document['ipv4']
  147. if isinstance(ipv4_info, dict):
  148. network.ipv4_dhcp = ipv4_info.get('dhcp', False)
  149. network.ipv4_addr = ipv4_info.get('addr', "")
  150. network.ipv4_override = ipv4_info.get('override', "")
  151. else:
  152. goon = False
  153. if 'speed' in document:
  154. network.speed = document['speed']
  155. return goon
  156. except json.JSONDecodeError:
  157. print("Error decoding JSON response")
  158. return False
  159. except requests.RequestException as e:
  160. print(f"Request error: {e}")
  161. return False
  162. except Exception as e:
  163. print(f"Unexpected error in get_network: {e}")
  164. return False
  165. # 验证IP地址格式合法性、检查IP地址是否为IPv4地址、发生HTTP请求来设置IP地址
  166. def put_override(self, override):
  167. goon = True
  168. result = ""
  169. try:
  170. if not re.match(r'^[0-9.]+$', override):
  171. goon = False
  172. result = "put_override: not ipv4 format"
  173. return goon, result
  174. if "/" not in override:
  175. goon = False
  176. result = "put_override: format is wrong"
  177. return goon, result
  178. ip_part = override.split('/')[0]
  179. try:
  180. ip = ipaddress.ip_address(ip_part)
  181. if not isinstance(ip, ipaddress.IPv4Address):
  182. goon = False
  183. result = "put_override: wrong ip format\r\n"
  184. return goon, result
  185. except ValueError:
  186. goon = False
  187. result = "put_override: wrong ip format\r\n"
  188. return goon, result
  189. if goon:
  190. result = ""
  191. cmdback = self.put_async_http('/api/v1/system/network/override', override)
  192. if 'HTTP/1.1 200 OK' in cmdback:
  193. result = 'HTTP/1.1 200 OK'
  194. else:
  195. goon = False
  196. result = "put_override: operation failed"
  197. except Exception as e:
  198. goon = False
  199. result = f"put_override: error - {str(e)}"
  200. return goon, result
  201. # 删除静态模式配置
  202. def delete_override(self):
  203. goon = True
  204. result = ""
  205. try:
  206. response = requests.delete('/api/v1/system/network/override')
  207. cmdback = response.text
  208. if 'HTTP/1.1 200 OK' in cmdback:
  209. result = 'HTTP/1.1 200 OK'
  210. else:
  211. goon = False
  212. result = "delete_override: operation failed"
  213. except requests.RequestException as e:
  214. goon = False
  215. result = f"delete_override: request error - {str(e)}"
  216. return goon, result
  217. # 执行系统重置
  218. def put_reset(self):
  219. result = ""
  220. goon = True
  221. try:
  222. response = requests.put('/api/v1/system/reset', json={'reset': True})
  223. cmdback = response.text
  224. if 'HTTP/1.1 200 OK' in cmdback:
  225. result = 'HTTP/1.1 200 OK'
  226. else:
  227. goon = False
  228. result = "put_reset: operation failed"
  229. except requests.RequestException as e:
  230. goon = False
  231. result = f"put_reset: request error - {str(e)}"
  232. return goon, result
  233. # 获取传感器的概述信息
  234. async def get_overview(self, overview: OverView):
  235. goon = True
  236. OVERVIEW_FIELDS = {
  237. 'scanfreq': ('scanfreq', int),
  238. 'motor_rpm': ('motor_rpm', int),
  239. 'laser_enable': ('laser_enable', bool),
  240. 'resolution': ('resolution', float),
  241. 'scan_range': ('scan_range', {
  242. 'start': ('start', int),
  243. 'stop': ('stop', int)
  244. }),
  245. 'filter': ('filter', {
  246. 'level': ('level', int),
  247. 'min_angle': ('min_angle', int),
  248. 'max_angle': ('max_angle', int),
  249. 'neighbors': ('neighbors', int),
  250. 'window': ('window', int)
  251. }),
  252. 'host': ('host', {
  253. 'ip': ('ip', str),
  254. 'port': ('port', int)
  255. })
  256. }
  257. try:
  258. cmdback = await self.get_async_http('/api/v1/sensor/overview')
  259. document = json.loads(cmdback)
  260. if not isinstance(document, dict):
  261. return False
  262. for field_name, (json_key, value_type) in OVERVIEW_FIELDS.items():
  263. if isinstance(value_type, dict):
  264. if json_key in document:
  265. nested_data = document[json_key]
  266. for nested_field, (nested_key, nested_type) in value_type.items():
  267. if nested_key in nested_data:
  268. setattr(overview, field_name + '_' + nested_field, nested_type(nested_data[nested_key]))
  269. else:
  270. print(f"Missing nested key: {nested_key}")
  271. goon = False
  272. else:
  273. print(f"Missing JSON key: {json_key}")
  274. goon = False
  275. else:
  276. if json_key in document:
  277. setattr(overview, field_name, value_type(document[json_key]))
  278. else:
  279. goon = False
  280. except json.JSONDecodeError as e:
  281. print(f"JSON Decode Error: {e}")
  282. goon = False
  283. except Exception as e:
  284. print(f"Unexpected error: {e}")
  285. goon = False
  286. return goon
  287. # 设置扫描频率
  288. def put_scanfreq(freq):
  289. try:
  290. freq_tep = int(freq)
  291. except ValueError:
  292. return False, "put_scanfreq: frequency must be an integer"
  293. if freq_tep not in [10, 20, 25, 30]:
  294. return False, "put_scanfreq: wrong freq"
  295. freq_str = str(freq_tep)
  296. try:
  297. response = requests.put('http://192.168.8.2/api/v1/sensor/scanfreq', data=freq_str)
  298. if response.status_code == 200:
  299. return True, "Frequency updated successfully"
  300. else:
  301. return False, f"put_scanfreq: operate failed - {response.text}"
  302. except requests.RequestException as e:
  303. return False, f"put_scanfreq: request error - {str(e)}"
  304. # 获取扫描频率
  305. async def get_scanfreq(self):
  306. result = ""
  307. goon = True
  308. try:
  309. cmdback = await self.get_async_http('/api/v1/sensor/scanfreq')
  310. document = json.loads(cmdback)
  311. if not isinstance(document, dict):
  312. goon = False
  313. else:
  314. if 'freq' in document:
  315. output_freq = document['freq']
  316. result = str(output_freq)
  317. else:
  318. goon = False
  319. except requests.RequestException:
  320. goon = False
  321. except json.JSONDecodeError:
  322. goon = False
  323. return goon, result
  324. # 获取激光状态
  325. def get_motor_rpm(self):
  326. motor_rpm = ""
  327. goon = True
  328. try:
  329. cmdback = self.get_async_http('/api/v1/sensor/motor_rpm')
  330. try:
  331. document = json.loads(cmdback)
  332. except json.JSONDecodeError:
  333. return False, ""
  334. if not isinstance(document, dict):
  335. return False, ""
  336. if 'rpm' in document:
  337. try:
  338. output_rpm = int(document['rpm'])
  339. motor_rpm = str(output_rpm)
  340. except (ValueError, TypeError):
  341. goon = False
  342. else:
  343. goon = False
  344. except requests.RequestException:
  345. goon = False
  346. return goon, motor_rpm
  347. # 切换激光状态
  348. async def get_laser_enable(self):
  349. laser_state = ""
  350. goon = True
  351. try:
  352. cmdback = await self.get_async_http('/api/v1/sensor/laser_enable')
  353. try:
  354. document = json.loads(cmdback)
  355. except json.JSONDecodeError:
  356. return False, "false"
  357. if not isinstance(document, dict):
  358. return False, "false"
  359. if 'HTTP/1.1 200 OK' in document:
  360. goon = 'HTTP/1.1 200 OK'
  361. else:
  362. goon = False
  363. except requests.RequestException:
  364. goon = False
  365. laser_state = "true" if goon else "false"
  366. return goon, laser_state
  367. # 获取雷达当前水平角分辨率
  368. def put_laser_enable(self, config_state):
  369. goon = True
  370. if config_state == "true":
  371. config_state = "true"
  372. elif config_state == "false":
  373. config_state = "false"
  374. else:
  375. goon = False
  376. config_state = "put_laser_enable: wrong parameter"
  377. if goon:
  378. try:
  379. cmdback = self.put_async_http('/api/v1/sensor/laser_enable', config_state)
  380. if not cmdback.startswith('HTTP/1.1 200 OK'):
  381. goon = False
  382. config_state = "put_laser_enable: operation failed"
  383. else:
  384. config_state = "true"
  385. except requests.RequestException:
  386. goon = False
  387. config_state = "put_laser_enable: request error"
  388. return goon, config_state
  389. # 获取激光分辨率
  390. async def get_resolution(self, overview: OverView):
  391. resolution = ""
  392. goon = True
  393. try:
  394. cmdback = await self.get_async_http('/api/v1/sensor/resolution')
  395. try:
  396. document = json.loads(cmdback)
  397. except json.JSONDecodeError:
  398. return False, ""
  399. if not isinstance(document, dict):
  400. goon = False
  401. else:
  402. if 'resolution' in document:
  403. output_resolution = document['resolution']
  404. overview.resolution = str(output_resolution)
  405. else:
  406. goon = False
  407. except requests.RequestException:
  408. goon = False
  409. return goon, overview.resolution
  410. # 获取激光扫描起始角度
  411. async def get_scan_range(self, scan_range: ScanRange):
  412. goon = True
  413. try:
  414. cmdback = await self.get_async_http('/api/v1/sensor/scan_range')
  415. try:
  416. document = json.loads(cmdback)
  417. except json.JSONDecodeError:
  418. return False, scan_range
  419. if not isinstance(document, dict):
  420. goon = False
  421. else:
  422. if 'scan_range' in document:
  423. value = document['scan_range']
  424. scan_range.start = value['start']
  425. scan_range.stop = value['stop']
  426. else:
  427. goon = False
  428. except requests.RequestException:
  429. goon = False
  430. return goon, scan_range
  431. # 获取激光扫描起始角度
  432. async def get_laser_start(self, scan_range: ScanRange):
  433. goon = True
  434. try:
  435. cmdback = await self.get_async_http('/api/v1/sensor/scan_range/start')
  436. try:
  437. document = json.loads(cmdback)
  438. if isinstance(document, dict) and 'start' in document:
  439. output_start = document['start']
  440. scan_range.start = output_start
  441. else:
  442. goon = False
  443. except json.JSONDecodeError as e:
  444. return False, scan_range
  445. except Exception as e:
  446. goon = False
  447. return goon, scan_range
  448. # 获取激光扫描停止角度
  449. async def get_laser_stop(self, scan_range: ScanRange):
  450. goon = True
  451. try:
  452. cmdback = await self.get_async_http('/api/v1/sensor/scan_range/stop')
  453. try:
  454. document = json.loads(cmdback)
  455. if isinstance(document, dict) and 'stop' in document:
  456. output_stop = document['stop']
  457. scan_range.stop = output_stop
  458. else:
  459. goon = False
  460. except json.JSONDecodeError as e:
  461. return False, scan_range
  462. except Exception as e:
  463. goon = False
  464. return goon, scan_range
  465. # 设置激光扫描开始角度
  466. async def put_laser_start(self, scan_range: ScanRange):
  467. goon = True
  468. error_message = ""
  469. start_freq = scan_range.start
  470. if start_freq > 315 or start_freq < 45:
  471. goon = False
  472. error_message = "put_laser_start: start must < 315 and > 45"
  473. return goon, scan_range, error_message
  474. if goon:
  475. temp_scan_range = ScanRange()
  476. stop_success, temp_scan_range = await self.get_laser_stop(temp_scan_range)
  477. if not stop_success:
  478. goon = False
  479. error_message = "Failed to retrieve current stop position"
  480. return goon, scan_range, error_message
  481. if start_freq >= temp_scan_range.stop:
  482. goon = False
  483. error_message = "put_laser_start: start must > stop"
  484. return goon, scan_range, error_message
  485. if goon:
  486. try:
  487. start_str = str(start_freq)
  488. cmdback = await self.put_async_http('/api/v1/sensor/scan_range/start', start_str)
  489. if not cmdback.startswith('HTTP/1.1 200 OK'):
  490. goon = False
  491. error_message = "put_laser_start: operation failed"
  492. return goon, scan_range, error_message
  493. except Exception as e:
  494. goon = False
  495. error_message = f"put_laser_start: operation failed - {str(e)}"
  496. return goon, scan_range, error_message
  497. return goon, scan_range, error_message
  498. # 设置激光扫描结束角度
  499. async def put_laser_stop(self, scan_range: ScanRange):
  500. goon = True
  501. error_message = ""
  502. stop_freq = scan_range.stop
  503. if stop_freq > 315 or stop_freq < 45:
  504. goon = False
  505. error_message = "put_laser_stop: stop must < 315 and > 45"
  506. return goon, scan_range, error_message
  507. if goon:
  508. try:
  509. stop_str = str(stop_freq)
  510. cmdback = await self.put_async_http('/api/v1/sensor/scan_range/stop', stop_str)
  511. # 验证响应
  512. if not cmdback.startswith('HTTP/1.1 200 OK'):
  513. goon = False
  514. error_message = "put_laser_stop: operation failed"
  515. return goon, scan_range, error_message
  516. except Exception as e:
  517. goon = False
  518. error_message = f"put_laser_stop: operation failed - {str(e)}"
  519. return goon, scan_range, error_message
  520. return goon, scan_range, error_message
  521. # 获取滤波器的设置
  522. async def get_filter_level(self, filter: Filter):
  523. goon = True
  524. try:
  525. cmdback = await self.get_async_http('/api/v1/sensor/filter')
  526. document = json.loads(cmdback)
  527. if not isinstance(document, dict):
  528. goon = False
  529. else:
  530. if 'filter' in document:
  531. value = document['filter']
  532. filter.level = value['level']
  533. filter.window = value['window']
  534. filter.min_angle = value['min_angle']
  535. filter.max_angle = value['max_angle']
  536. filter.neighbors = value['neighbors']
  537. else:
  538. goon = False
  539. except (requests.RequestException, json.JSONDecodeError) as e:
  540. goon = False
  541. print(f"Error occurred: {str(e)}")
  542. return goon
  543. # 设置过滤级别
  544. async def put_filter_level(self, filter: Filter):
  545. try:
  546. level = filter.level
  547. if level not in [0, 1, 2, 3]:
  548. raise ValueError("put_filter_level: wrong level parameter")
  549. level_str = str(level)
  550. status, response_text = await self.put_async_http('/api/v1/sensor/filter/level', level_str)
  551. if status == 200:
  552. return True
  553. else:
  554. raise ValueError(f"put_filter_level: operation failed, status code: {status}")
  555. except Exception as e:
  556. print(str(e))
  557. return False
  558. # 获取过滤窗口设置
  559. def get_filter_window(self, filter: Filter):
  560. try:
  561. cmdback = self.get_async_http('/api/v1/sensor/filter/window')
  562. document = json.loads(cmdback)
  563. if 'window' in document:
  564. temp = document['window']
  565. filter.window = temp
  566. return True
  567. else:
  568. return False
  569. except (json.JSONDecodeError, Exception) as e:
  570. print(f"Error in get_filter_window: {e}")
  571. return False
  572. # 设置过滤窗口
  573. async def put_filter_window(self, filter: Filter):
  574. try:
  575. window_tep = filter.window
  576. if window_tep < 0:
  577. raise ValueError("put_filter_window: window must > 0")
  578. if window_tep > 10:
  579. raise ValueError("put_filter_window: window must <= 10")
  580. window_str = str(window_tep)
  581. status, response_text = await self.put_async_http('/api/v1/sensor/filter/window', window_str)
  582. if status == 200:
  583. return True
  584. else:
  585. raise ValueError(f"put_filter_level: operation failed, status code: {status}")
  586. except Exception as e:
  587. print(str(e))
  588. return False
  589. # 获取过滤最大角度设置并更新Filter对象
  590. async def get_filter_max_angle(self, filter: Filter):
  591. try:
  592. cmdback = await self.get_async_http('/api/v1/sensor/filter/max_angle')
  593. document = json.loads(cmdback)
  594. # 检查是否为有效的JSON对象
  595. if not isinstance(document, dict):
  596. print("Invalid JSON response: not an object")
  597. return False
  598. if 'max_angle' in document:
  599. temp = document['max_angle']
  600. filter.max_angle = int(temp)
  601. return True
  602. else:
  603. print(f"No key found in response")
  604. return False
  605. except json.JSONDecodeError:
  606. print("Invalid JSON response: unable to parse")
  607. return False
  608. except Exception as e:
  609. print(f"Error in get_filter_max_angle: {e}")
  610. return False
  611. # 设置过滤最大角度
  612. async def put_filter_max_angle(self, filter: Filter):
  613. try:
  614. max_angle_tep = filter.max_angle
  615. # 更严格的参数校验
  616. if not isinstance(max_angle_tep, int):
  617. raise TypeError("Max angle must be an integer")
  618. # 检查最大角度值的有效范围(根据实际需求调整)
  619. if max_angle_tep < 0:
  620. raise ValueError("Max angle must be >= 0")
  621. if max_angle_tep > 180: # 假设角度范围在0-180之间
  622. raise ValueError("Max angle must be <= 180")
  623. # 将最大角度值转换为字符串
  624. max_angle_str = str(max_angle_tep)
  625. status, response_text = await self.put_async_http('/api/v1/sensor/filter/max_angle', max_angle_str)
  626. if status == 200:
  627. return True
  628. else:
  629. raise ValueError(f"put_filter_level: operation failed, status code: {status}")
  630. except Exception as e:
  631. print(str(e))
  632. return False
  633. def get_filter_min_angle(self, filter: Filter):
  634. try:
  635. # 发送HTTP GET请求
  636. cmdback = self.get_async_http('/api/v1/sensor/filter/min_angle')
  637. document = json.loads(cmdback)
  638. # 检查返回的JSON对象是否包含特定的键
  639. if 'min_angle' in document:
  640. temp = document['min_angle']
  641. filter.min_angle = int(temp) # 更新Filter对象的min_angle属性
  642. return True
  643. else:
  644. print("No 'min_angle' key found in response")
  645. return False
  646. except json.JSONDecodeError:
  647. print("Invalid JSON response")
  648. return False
  649. except Exception as e:
  650. print(f"Error in get_filter_min_angle: {e}")
  651. return False
  652. # 设置过滤最小角度
  653. async def put_filter_min_angle(self, filter: Filter):
  654. try:
  655. # 获取最小角度值
  656. min_angle_tep = filter.min_angle
  657. if min_angle_tep < 0:
  658. print("put_filter_min_angle: min_angle must >= 0")
  659. return False
  660. if min_angle_tep > 359:
  661. print("put_filter_min_angle: min_angle must <= 359")
  662. return False
  663. max_angle_result = await self.get_filter_max_angle(filter) # 使用 await 等待结果
  664. if max_angle_result:
  665. max_angle_tep = filter.max_angle
  666. if min_angle_tep > max_angle_tep:
  667. print("put_filter_min_angle: max_angle must >= min_angle")
  668. return False
  669. else:
  670. print("Failed to get max angle for comparison")
  671. return False
  672. min_angle_str = str(min_angle_tep)
  673. cmdback = await self.put_async_http('/api/v1/sensor/filter/min_angle', min_angle_str) # 使用 await 等待结果
  674. # if cmdback.startswith('HTTP/1.1 200 OK'):
  675. # return True
  676. # else:
  677. # print("put_filter_min_angle: operation failed")
  678. # return False
  679. except Exception as e:
  680. print(f"Unexpected error in put_filter_min_angle: {e}")
  681. return False
  682. # 获取过滤邻居设置并更新Filter对象
  683. def get_filter_neighbors(self, filter: Filter):
  684. try:
  685. cmdback = self.get_async_http('/api/v1/sensor/filter/neighbors')
  686. document = json.loads(cmdback)
  687. if not isinstance(document, dict):
  688. print("Invalid JSON response: not an object")
  689. return False
  690. # 检查返回的JSON对象是否包含特定的键
  691. if 'neighbors' in document:
  692. # 获取邻居数量并更新Filter对象的neighbors属性
  693. temp = document['neighbors']
  694. filter.neighbors = int(temp) # 确保将其转换为整数
  695. return True
  696. else:
  697. return False
  698. except json.JSONDecodeError:
  699. print("Invalid JSON response: unable to parse")
  700. return False
  701. except Exception as e:
  702. print(f"Error in get_filter_neighbors: {e}")
  703. return False
  704. # 设置过滤邻居数量
  705. async def put_filter_neighbors(self, filter: Filter):
  706. try:
  707. neighbors_tep = filter.neighbors
  708. if neighbors_tep < 0:
  709. print("put_filter_neighbors: neighbors must > 0")
  710. return False
  711. if neighbors_tep > 10:
  712. print("put_filter_neighbors: neighbors must < 10")
  713. return False
  714. neighbors_str = str(neighbors_tep)
  715. status, response_text = await self.put_async_http('/api/v1/sensor/filter/neighbors', neighbors_str)
  716. if status == 200:
  717. return True
  718. else:
  719. print("put_filter_neighbors: operation failed")
  720. return False
  721. except Exception as e:
  722. print(f"Unexpected error in put_filter_neighbors: {e}")
  723. return False
  724. # 获取主机配置并更新Host对象
  725. async def get_host(self, host: Host):
  726. try:
  727. cmdback = await self.get_async_http('/api/v1/sensor/host')
  728. document = json.loads(cmdback)
  729. if not isinstance(document, dict):
  730. print("Invalid JSON response: not an object")
  731. return False
  732. if 'host' in document:
  733. value = document['host']
  734. host.ip = value['ip']
  735. host.port = value['port']
  736. return True
  737. else:
  738. return False
  739. except json.JSONDecodeError:
  740. print("Invalid JSON response: unable to parse")
  741. return False
  742. except Exception as e:
  743. print(f"Error in get_host: {e}")
  744. return False
  745. # 获取主机IP并更新Host对象
  746. async def get_host_ip(self, host: Host):
  747. try:
  748. cmdback = await self.get_async_http('/api/v1/sensor/host/ip')
  749. document = json.loads(cmdback)
  750. if not isinstance(document, dict):
  751. print("Invalid JSON response: not an object")
  752. return False
  753. if 'ip' in document:
  754. host.ip = document['ip']
  755. return True
  756. else:
  757. return False
  758. except json.JSONDecodeError:
  759. print("Invalid JSON response: unable to parse")
  760. return False
  761. except Exception as e:
  762. print(f"Error in get_host_ip: {e}")
  763. return False
  764. # 设置主机IP地址
  765. async def put_host_ip(self, host: Host):
  766. try:
  767. ip = host.ip
  768. ip_size = len(ip)
  769. for i in range(ip_size):
  770. if not ((ip[i] >= '0' and ip[i] <= '9') or ip[i] == '.'):
  771. print("put_host_ip: not ipv4 format")
  772. return False
  773. try:
  774. parts = ip.split('.')
  775. if len(parts) != 4:
  776. print("put_host_ip: not ipv4 format")
  777. return False
  778. for part in parts:
  779. num = int(part)
  780. if num < 0 or num > 255:
  781. print("put_host_ip: not ipv4 format")
  782. return False
  783. except (ValueError, IndexError):
  784. print("put_host_ip: not ipv4 format")
  785. return False
  786. status, response_text = await self.put_async_http('/api/v1/sensor/host/ip', ip)
  787. if status == 200:
  788. return True
  789. else:
  790. print("put_filter_neighbors: operation failed")
  791. return False
  792. except Exception as e:
  793. print(f"Unexpected error in put_filter_neighbors: {e}")
  794. return False
  795. # 获取主机端口并更新Host对象
  796. async def get_host_port(self, host: Host):
  797. try:
  798. cmdback = await self.get_async_http('/api/v1/sensor/host/port')
  799. document = json.loads(cmdback)
  800. if not isinstance(document, dict):
  801. print("Invalid JSON response: not an object")
  802. return False
  803. if 'port' in document:
  804. temp = document['port']
  805. host.port = int(temp)
  806. return True
  807. else:
  808. return False
  809. except json.JSONDecodeError:
  810. print("Invalid JSON response: unable to parse")
  811. return False
  812. except Exception as e:
  813. print(f"Error in get_host_port: {e}")
  814. return False
  815. # 设置主机端口
  816. async def put_host_port(self, host: Host):
  817. goon = True
  818. port = str(host.port)
  819. cmdback = await self.put_async_http('/api/v1/sensor/host/port', port)
  820. res = cmdback.find('HTTP/1.1 200 OK')
  821. if res == -1:
  822. goon = False
  823. message = "put_host_port: operation failed"
  824. else:
  825. message = f"Operation succeeded for IP: {port}"
  826. return goon, message
  827. # 发送 GET 请求并处理响应
  828. def get_http(self, target: str):
  829. try:
  830. full_url = f"{self.base_url}{target}"
  831. headers = {
  832. 'User-Agent': 'Python-Requests',
  833. 'Connection': 'close'
  834. }
  835. response = requests.get(full_url, headers=headers)
  836. response.raise_for_status()
  837. response_text = response.text
  838. start = response_text.find("{")
  839. end = response_text.rfind("}")
  840. if start != -1 and end != -1 and end > start:
  841. cutstring = response_text[start:end + 1]
  842. return cutstring
  843. return ""
  844. except requests.RequestException as e:
  845. print(f"HTTP 请求错误: {e}")
  846. return ""
  847. except Exception as e:
  848. print(f"处理响应时发生错误: {e}")
  849. return ""
  850. # 发送 PUT 请求并处理响应
  851. def put_http(self, target: str, message: str):
  852. try:
  853. full_url = "{}{}".format(self.base_url, target)
  854. headers = {
  855. 'User-Agent': 'Python-Requests',
  856. 'Content-Type': 'application/json',
  857. 'Connection': 'close'
  858. }
  859. response = requests.put(full_url, headers=headers, data=message)
  860. response.raise_for_status()
  861. return response.text
  862. except requests.RequestException as e:
  863. print(f"HTTP 请求错误: {e}")
  864. return ""
  865. except Exception as e:
  866. print(f"处理响应时发生错误: {e}")
  867. return ""
  868. # 发送 DELETE 请求并处理响应
  869. def delete_http(self, target: str):
  870. try:
  871. full_url = "{}{}".format(self.base_url, target)
  872. headers = {
  873. 'User-Agent': 'Python-Requests',
  874. 'Connection': 'close'
  875. }
  876. response = requests.delete(full_url, headers=headers)
  877. response.raise_for_status()
  878. return response.text
  879. except requests.RequestException as e:
  880. print(f"HTTP 请求错误: {e}")
  881. return ""
  882. except Exception as e:
  883. print(f"处理响应时发生错误: {e}")
  884. return ""
  885. # 发送异步 GET 请求并处理响应
  886. async def get_async_http(self, target: str):
  887. full_url = f"{self.base_url}{target}"
  888. try:
  889. async with aiohttp.ClientSession() as session:
  890. async with session.get(full_url) as response:
  891. response_text = await response.text()
  892. return response_text
  893. except aiohttp.ClientError as e:
  894. print(f"HTTP 请求错误: {e}")
  895. return ""
  896. except Exception as e:
  897. print(f"处理响应时发生错误: {e}")
  898. return ""
  899. # 发送异步 PUT 请求并处理响应
  900. async def put_async_http(self, target: str, message: str):
  901. full_url = f"{self.base_url}{target}"
  902. try:
  903. async with aiohttp.ClientSession() as session:
  904. headers = {
  905. 'Content-Type': 'application/json',
  906. 'User-Agent': 'Python-aiohttp',
  907. 'Connection': 'close'
  908. }
  909. async with session.put(full_url,
  910. headers=headers,
  911. data=message,
  912. timeout=aiohttp.ClientTimeout(total=10)) as response:
  913. response.raise_for_status()
  914. response_text = await response.json()
  915. return response.status, response_text
  916. except aiohttp.ClientResponseError as e:
  917. print(f"HTTP 请求错误: {e}")
  918. return e.status, f"put_async_http: can't connect to http - {str(e)}"
  919. except asyncio.TimeoutError:
  920. print("请求超时")
  921. return 408, "put_async_http: request timeout"
  922. except Exception as e:
  923. print(f"处理响应时发生错误: {e}")
  924. return 500, f"put_async_http: unexpected error - {str(e)}"
  925. # 发送异步 DELETE 请求并处理响应
  926. async def delete_async_http(self, target: str) -> str:
  927. full_url = f"{self.base_url}{target}"
  928. try:
  929. async with aiohttp.ClientSession() as session:
  930. headers = {
  931. 'User-Agent': 'Python-aiohttp',
  932. 'Connection': 'close'
  933. }
  934. async with session.delete(full_url,
  935. headers=headers,
  936. timeout=aiohttp.ClientTimeout(total=10)) as response:
  937. response.raise_for_status()
  938. response_text = await response.text()
  939. if not response_text:
  940. return "delete_async_http: can't connect to http"
  941. start = response_text.find("{")
  942. end = response_text.rfind("}")
  943. if start != -1 and end != -1 and end >= start:
  944. return response_text[start:end + 1]
  945. return response_text
  946. except aiohttp.ClientError as e:
  947. print(f"HTTP 请求错误: {e}")
  948. return f"delete_async_http: can't connect to http - {str(e)}"
  949. except asyncio.TimeoutError:
  950. print("请求超时")
  951. return "delete_async_http: request timeout"
  952. except Exception as e:
  953. print(f"处理响应时发生错误: {e}")
  954. return f"delete_async_http: unexpected error - {str(e)}"
  955. # 检查本地和目标 IP 地址的有效性
  956. def check_ipconfig(self) -> bool:
  957. goon = True
  958. try:
  959. try:
  960. local_ip_obj = ipaddress.ip_address(self.local_ip)
  961. if not isinstance(local_ip_obj, ipaddress.IPv4Address):
  962. raise ValueError("Not an IPv4 address")
  963. except (ValueError, TypeError):
  964. goon = False
  965. self.local_ip = self.HOST_IP_DEFAULT
  966. print(f"Invalid local IP, using default: {self.local_ip}")
  967. try:
  968. web_ip_obj = ipaddress.ip_address(self.web_ip)
  969. if not isinstance(web_ip_obj, ipaddress.IPv4Address):
  970. raise ValueError("Not an IPv4 address")
  971. except (ValueError, TypeError):
  972. goon = False
  973. self.web_ip = self.HTTP_IP_DEFAULT
  974. print(f"Invalid web IP, using default: {self.web_ip}")
  975. except Exception as e:
  976. print(f"Unexpected error in check_ipconfig: {e}")
  977. goon = False
  978. return goon