src/eric7/MicroPython/Devices/DeviceBase.py

branch
mpy_network
changeset 9989
286c2a21f36f
parent 9979
dbafba79461d
child 10019
e56089d00750
equal deleted inserted replaced
9988:1ba9d07ba9da 9989:286c2a21f36f
116 @type QObject 116 @type QObject
117 """ 117 """
118 super().__init__(parent) 118 super().__init__(parent)
119 119
120 self._deviceType = deviceType 120 self._deviceType = deviceType
121 self._interface = microPythonWidget.deviceInterface() 121 self._interface = None
122 self.microPython = microPythonWidget 122 self.microPython = microPythonWidget
123 self._deviceData = {} # dictionary with essential device data 123 self._deviceData = {} # dictionary with essential device data
124 124
125 self._submitMode = "raw" # default is 'raw' mode to submit commands 125 self._submitMode = "raw" # default is 'raw' mode to submit commands
126 126
135 @type bool 135 @type bool
136 """ 136 """
137 self._deviceData = {} 137 self._deviceData = {}
138 138
139 if connected: 139 if connected:
140 self._interface = self.microPython.deviceInterface()
140 with contextlib.suppress(OSError): 141 with contextlib.suppress(OSError):
141 self._deviceData = self.__getDeviceData() 142 self._deviceData = self.__getDeviceData()
142 self._deviceData["local_mip"] = ( 143 self._deviceData["local_mip"] = (
143 not self._deviceData["mip"] and not self._deviceData["upip"] 144 not self._deviceData["mip"] and not self._deviceData["upip"]
144 ) 145 )
147 ( 148 (
148 self._deviceData["ethernet"], 149 self._deviceData["ethernet"],
149 self._deviceData["ethernet_type"], 150 self._deviceData["ethernet_type"],
150 ) = self.hasEthernet() 151 ) = self.hasEthernet()
151 self._deviceData["ntp"] = self.hasNetworkTime() 152 self._deviceData["ntp"] = self.hasNetworkTime()
153 else:
154 self._interface = None
152 155
153 def getDeviceType(self): 156 def getDeviceType(self):
154 """ 157 """
155 Public method to get the device type. 158 Public method to get the device type.
156 159
379 return deviceDirectory 382 return deviceDirectory
380 else: 383 else:
381 # user cancelled 384 # user cancelled
382 return "" 385 return ""
383 386
387 def executeCommands(self, commands, *, mode="raw", timeout=0):
388 """
389 Public method to send commands to the connected device and return the
390 result.
391
392 If no connected interface is available, empty results will be returned.
393
394 @param commands list of commands to be executed
395 @type str or list of str
396 @keyparam mode submit mode to be used (one of 'raw' or 'paste') (defaults to
397 'raw')
398 @type str
399 @keyparam timeout per command timeout in milliseconds (0 for configured default)
400 (defaults to 0)
401 @type int (optional)
402 @return tuple containing stdout and stderr output of the device
403 @rtype tuple of (bytes, bytes)
404 """
405 if self._interface is None:
406 return b"", b""
407
408 return self._interface.execute(commands, mode=mode, timeout=timeout)
409
384 def sendCommands(self, commandsList): 410 def sendCommands(self, commandsList):
385 """ 411 """
386 Public method to send a list of commands to the device. 412 Public method to send a list of commands to the device.
387 413
388 @param commandsList list of commands to be sent to the device 414 @param commandsList list of commands to be sent to the device
389 @type list of str 415 @type list of str
390 """ 416 """
391 if self._submitMode == "raw": 417 if self._interface is not None:
392 rawOn = [ # sequence of commands to enter raw mode 418 self._interface.executeAsync(commandsList, self._submitMode)
393 b"\x02", # Ctrl-B: exit raw repl (just in case)
394 b"\r\x03\x03\x03", # Ctrl-C three times: interrupt any running program
395 b"\r\x01", # Ctrl-A: enter raw REPL
396 ]
397 newLine = [
398 b'print("\\n")\r',
399 ]
400 commands = [c.encode("utf-8)") + b"\r" for c in commandsList]
401 commands.append(b"\r")
402 commands.append(b"\x04")
403 rawOff = [b"\x02", b"\x02"]
404 commandSequence = rawOn + newLine + commands + rawOff
405 self._interface.executeAsync(commandSequence)
406 elif self._submitMode == "paste":
407 commands = b"\n".join([c.encode("utf-8)") for c in commandsList])
408 commandSequence = ["@PasteOn@", commands]
409 self._interface.executeAsyncPaste(commandSequence)
410 419
411 @pyqtSlot() 420 @pyqtSlot()
412 def handleDataFlood(self): 421 def handleDataFlood(self):
413 """ 422 """
414 Public slot handling a data floof from the device. 423 Public slot handling a data floof from the device.
541 print(False) 550 print(False)
542 del __os_ 551 del __os_
543 """.format( 552 """.format(
544 repr(pathname) 553 repr(pathname)
545 ) 554 )
546 out, err = self._interface.execute(command, mode=self._submitMode) 555 out, err = self.executeCommands(command, mode=self._submitMode)
547 if err: 556 if err:
548 raise OSError(self._shortError(err)) 557 raise OSError(self._shortError(err))
549 return out.strip() == b"True" 558 return out.strip() == b"True"
550 559
551 def ls(self, dirname=""): 560 def ls(self, dirname=""):
563 print(__os_.listdir('{0}')) 572 print(__os_.listdir('{0}'))
564 del __os_ 573 del __os_
565 """.format( 574 """.format(
566 dirname 575 dirname
567 ) 576 )
568 out, err = self._interface.execute(command, mode=self._submitMode) 577 out, err = self.executeCommands(command, mode=self._submitMode)
569 if err: 578 if err:
570 raise OSError(self._shortError(err)) 579 raise OSError(self._shortError(err))
571 return ast.literal_eval(out.decode("utf-8")) 580 return ast.literal_eval(out.decode("utf-8"))
572 581
573 def lls(self, dirname="", fullstat=False, showHidden=False): 582 def lls(self, dirname="", fullstat=False, showHidden=False):
615 print(listdir_stat('{0}', {1})) 624 print(listdir_stat('{0}', {1}))
616 del __os_, stat, listdir_stat, is_visible 625 del __os_, stat, listdir_stat, is_visible
617 """.format( 626 """.format(
618 dirname, showHidden 627 dirname, showHidden
619 ) 628 )
620 out, err = self._interface.execute(command, mode=self._submitMode) 629 out, err = self.executeCommands(command, mode=self._submitMode)
621 if err: 630 if err:
622 raise OSError(self._shortError(err)) 631 raise OSError(self._shortError(err))
623 fileslist = ast.literal_eval(out.decode("utf-8")) 632 fileslist = ast.literal_eval(out.decode("utf-8"))
624 if fileslist is None: 633 if fileslist is None:
625 return None 634 return None
643 __os_.chdir('{0}') 652 __os_.chdir('{0}')
644 del __os_ 653 del __os_
645 """.format( 654 """.format(
646 dirname 655 dirname
647 ) 656 )
648 out, err = self._interface.execute(command, mode=self._submitMode) 657 out, err = self.executeCommands(command, mode=self._submitMode)
649 if err: 658 if err:
650 raise OSError(self._shortError(err)) 659 raise OSError(self._shortError(err))
651 660
652 def pwd(self): 661 def pwd(self):
653 """ 662 """
660 command = """ 669 command = """
661 import os as __os_ 670 import os as __os_
662 print(__os_.getcwd()) 671 print(__os_.getcwd())
663 del __os_ 672 del __os_
664 """ 673 """
665 out, err = self._interface.execute(command, mode=self._submitMode) 674 out, err = self.executeCommands(command, mode=self._submitMode)
666 if err: 675 if err:
667 raise OSError(self._shortError(err)) 676 raise OSError(self._shortError(err))
668 return out.decode("utf-8").strip() 677 return out.decode("utf-8").strip()
669 678
670 def rm(self, filename): 679 def rm(self, filename):
685 raise err 694 raise err
686 del __os_ 695 del __os_
687 """.format( 696 """.format(
688 filename 697 filename
689 ) 698 )
690 out, err = self._interface.execute(command, mode=self._submitMode) 699 out, err = self.executeCommands(command, mode=self._submitMode)
691 if err: 700 if err:
692 raise OSError(self._shortError(err)) 701 raise OSError(self._shortError(err))
693 702
694 def rmrf(self, name, recursive=False, force=False): 703 def rmrf(self, name, recursive=False, force=False):
695 """ 704 """
732 print(remove_file('{0}', {1}, {2})) 741 print(remove_file('{0}', {1}, {2}))
733 del __os_, remove_file 742 del __os_, remove_file
734 """.format( 743 """.format(
735 name, recursive, force 744 name, recursive, force
736 ) 745 )
737 out, err = self._interface.execute( 746 out, err = self.executeCommands(
738 command, mode=self._submitMode, timeout=20000 747 command, mode=self._submitMode, timeout=20000
739 ) 748 )
740 if err: 749 if err:
741 raise OSError(self._shortError(err)) 750 raise OSError(self._shortError(err))
742 return ast.literal_eval(out.decode("utf-8")) 751 return ast.literal_eval(out.decode("utf-8"))
757 __os_.mkdir('{0}') 766 __os_.mkdir('{0}')
758 del __os_ 767 del __os_
759 """.format( 768 """.format(
760 dirname 769 dirname
761 ) 770 )
762 out, err = self._interface.execute(command, mode=self._submitMode) 771 out, err = self.executeCommands(command, mode=self._submitMode)
763 if err: 772 if err:
764 raise OSError(self._shortError(err)) 773 raise OSError(self._shortError(err))
765 774
766 def rmdir(self, dirname): 775 def rmdir(self, dirname):
767 """ 776 """
784 raise 793 raise
785 del __os_ 794 del __os_
786 """.format( 795 """.format(
787 dirname 796 dirname
788 ) 797 )
789 out, err = self._interface.execute(command, mode=self._submitMode) 798 out, err = self.executeCommands(command, mode=self._submitMode)
790 if err: 799 if err:
791 raise OSError(self._shortError(err)) 800 raise OSError(self._shortError(err))
792 801
793 def put(self, hostFileName, deviceFileName=None): 802 def put(self, hostFileName, deviceFileName=None):
794 """ 803 """
846 "del f, fd", 855 "del f, fd",
847 ] 856 ]
848 ) 857 )
849 command = "\n".join(commands) 858 command = "\n".join(commands)
850 859
851 out, err = self._interface.execute(command, mode=self._submitMode) 860 out, err = self.executeCommands(command, mode=self._submitMode)
852 if err: 861 if err:
853 raise OSError(self._shortError(err)) 862 raise OSError(self._shortError(err))
854 return True 863 return True
855 864
856 def get(self, deviceFileName, hostFileName=None): 865 def get(self, deviceFileName, hostFileName=None):
915 send_data() 924 send_data()
916 del send_data 925 del send_data
917 """.format( 926 """.format(
918 deviceFileName 927 deviceFileName
919 ) 928 )
920 out, err = self._interface.execute(command, mode=self._submitMode) 929 out, err = self.executeCommands(command, mode=self._submitMode)
921 if err: 930 if err:
922 raise OSError(self._shortError(err)) 931 raise OSError(self._shortError(err))
923 932
924 # write the received bytes to the local file 933 # write the received bytes to the local file
925 # convert eol to "\n" 934 # convert eol to "\n"
960 return infodict 969 return infodict
961 970
962 print(fsinfo()) 971 print(fsinfo())
963 del __os_, fsinfo 972 del __os_, fsinfo
964 """ 973 """
965 out, err = self._interface.execute(command, mode=self._submitMode) 974 out, err = self.executeCommands(command, mode=self._submitMode)
966 if err: 975 if err:
967 raise OSError(self._shortError(err)) 976 raise OSError(self._shortError(err))
968 infodict = ast.literal_eval(out.decode("utf-8")) 977 infodict = ast.literal_eval(out.decode("utf-8"))
969 if infodict is None: 978 if infodict is None:
970 return None 979 return None
1082 return res 1091 return res
1083 1092
1084 print(get_device_data()) 1093 print(get_device_data())
1085 del get_device_data 1094 del get_device_data
1086 """ 1095 """
1087 out, err = self._interface.execute(command, mode=self._submitMode) 1096 out, err = self.executeCommands(command, mode=self._submitMode)
1088 if err: 1097 if err:
1089 raise OSError(self._shortError(err)) 1098 raise OSError(self._shortError(err))
1090 return ast.literal_eval(out.decode("utf-8")) 1099 return ast.literal_eval(out.decode("utf-8"))
1091 1100
1092 def getBoardInformation(self): 1101 def getBoardInformation(self):
1196 return res 1205 return res
1197 1206
1198 print(get_board_info()) 1207 print(get_board_info())
1199 del get_board_info 1208 del get_board_info
1200 """ 1209 """
1201 out, err = self._interface.execute(command, mode=self._submitMode) 1210 out, err = self.executeCommands(command, mode=self._submitMode)
1202 if err: 1211 if err:
1203 raise OSError(self._shortError(err)) 1212 raise OSError(self._shortError(err))
1204 return ast.literal_eval(out.decode("utf-8")) 1213 return ast.literal_eval(out.decode("utf-8"))
1205 1214
1206 def getModules(self): 1215 def getModules(self):
1210 @return list of builtin modules 1219 @return list of builtin modules
1211 @rtype list of str 1220 @rtype list of str
1212 @exception OSError raised to indicate an issue with the device 1221 @exception OSError raised to indicate an issue with the device
1213 """ 1222 """
1214 commands = ["help('modules')"] 1223 commands = ["help('modules')"]
1215 out, err = self._interface.execute(commands, mode=self._submitMode) 1224 out, err = self.executeCommands(commands, mode=self._submitMode)
1216 if err: 1225 if err:
1217 raise OSError(self._shortError(err)) 1226 raise OSError(self._shortError(err))
1218 1227
1219 modules = [] 1228 modules = []
1220 for line in out.decode("utf-8").splitlines()[:-1]: 1229 for line in out.decode("utf-8").splitlines()[:-1]:
1253 ) 1262 )
1254 1263
1255 get_time() 1264 get_time()
1256 del get_time 1265 del get_time
1257 """ 1266 """
1258 out, err = self._interface.execute(command, mode=self._submitMode) 1267 out, err = self.executeCommands(command, mode=self._submitMode)
1259 if err: 1268 if err:
1260 if b"NotImplementedError" in err: 1269 if b"NotImplementedError" in err:
1261 return "<unsupported> <unsupported>" 1270 return "<unsupported> <unsupported>"
1262 raise OSError(self._shortError(err)) 1271 raise OSError(self._shortError(err))
1263 return out.decode("utf-8").strip() 1272 return out.decode("utf-8").strip()
1325 now.tm_sec, 1334 now.tm_sec,
1326 now.tm_yday, 1335 now.tm_yday,
1327 now.tm_isdst, 1336 now.tm_isdst,
1328 ), 1337 ),
1329 ) 1338 )
1330 out, err = self._interface.execute(command, mode=self._submitMode) 1339 out, err = self.executeCommands(command, mode=self._submitMode)
1331 if err: 1340 if err:
1332 raise OSError(self._shortError(err)) 1341 raise OSError(self._shortError(err))
1333 1342
1334 ################################################################## 1343 ##################################################################
1335 ## Methods below implement package management related methods 1344 ## Methods below implement package management related methods
1352 upip_install() 1361 upip_install()
1353 del upip_install 1362 del upip_install
1354 """.format( 1363 """.format(
1355 repr(packages) 1364 repr(packages)
1356 ) 1365 )
1357 return self._interface.execute(command, mode=self._submitMode, timeout=60000) 1366 return self.executeCommands(command, mode=self._submitMode, timeout=60000)
1358 1367
1359 def mipInstall(self, package, index=None, target=None, version=None, mpy=True): 1368 def mipInstall(self, package, index=None, target=None, version=None, mpy=True):
1360 """ 1369 """
1361 Public method to install packages using 'mip'. 1370 Public method to install packages using 'mip'.
1362 1371
1391 mip_install() 1400 mip_install()
1392 del mip_install 1401 del mip_install
1393 """.format( 1402 """.format(
1394 parameterStr 1403 parameterStr
1395 ) 1404 )
1396 return self._interface.execute(command, mode=self._submitMode, timeout=60000) 1405 return self.executeCommands(command, mode=self._submitMode, timeout=60000)
1397 1406
1398 def getLibPaths(self): 1407 def getLibPaths(self):
1399 """ 1408 """
1400 Public method to get the list of library paths contained in 'sys.path'. 1409 Public method to get the list of library paths contained in 'sys.path'.
1401 1410
1409 print([p for p in sys.path if p.endswith('/lib')]) 1418 print([p for p in sys.path if p.endswith('/lib')])
1410 1419
1411 lib_paths() 1420 lib_paths()
1412 del lib_paths 1421 del lib_paths
1413 """ 1422 """
1414 out, err = self._interface.execute(command, mode=self._submitMode) 1423 out, err = self.executeCommands(command, mode=self._submitMode)
1415 if err: 1424 if err:
1416 raise OSError(self._shortError(err)) 1425 raise OSError(self._shortError(err))
1417 1426
1418 return ast.literal_eval(out.decode("utf-8")) 1427 return ast.literal_eval(out.decode("utf-8"))
1419 1428

eric ide

mercurial