Browse Source

added file.list and more

Peter Magnusson 9 years ago
parent
commit
f059a13f26
2 changed files with 102 additions and 60 deletions
  1. 15 4
      README.md
  2. 87 56
      nodemcu-uploader.py

+ 15 - 4
README.md

@@ -3,18 +3,29 @@ nodemcu-uploader.py
 
 
 
 
 A simple tool for uploading files to the filesystem of an
 A simple tool for uploading files to the filesystem of an
-ESP8266 running nodeMcu.
+ESP8266 running nodeMcu as well as some other usefull commands.
 
 
 It should work on linux and windows and with any type of file 
 It should work on linux and windows and with any type of file 
-that fits the filesystem.
+that fits the filesystem, binary or text.
 
 
 
 
 Usage
 Usage
 -----
 -----
-```
-./nodemcu-uploader.py --port /dev/ttyUSB0 --verbose init.lua README.md
+--port and --baud are set to default /dev/ttyUSB0 and 9600 respectively.
 
 
+###Upload
+Uploading a number of files
+```
+./nodemcu-uploader.py upload init.lua README.md nodemcu-uploader.py
+```
 
 
+###List files
+```
+./nodemcu-uploader.py --port com1 file list
 ```
 ```
 
 
+###Format filesystem
+```
+./nodemcu-uploader.py file format
+```
  
  

+ 87 - 56
nodemcu-uploader.py

@@ -1,3 +1,6 @@
+#!/usr/bin/env python
+# Copyright (C) 2015 Peter Magnusson
+
 # For NodeMcu version 0.9.4 build 2014-12-30 and newer.
 # For NodeMcu version 0.9.4 build 2014-12-30 and newer.
 
 
 import os
 import os
@@ -5,14 +8,13 @@ import serial
 import sys
 import sys
 import argparse
 import argparse
 import time
 import time
+import logging
+
+log = logging.getLogger(__name__)
 
 
 def minify(script):
 def minify(script):
     return ' '.join([line.strip() for line in script.split('\n')])
     return ' '.join([line.strip() for line in script.split('\n')])
 
 
-def log(msg):
-    sys.stdout.write(msg)
-    sys.stdout.flush()
-
 save_lua = \
 save_lua = \
 r"""
 r"""
 function recv_block(d)
 function recv_block(d)
@@ -58,20 +60,19 @@ class Uploader:
     TIMEOUT = 1
     TIMEOUT = 1
 
 
     def __init__(self, port = 0, baud = BAUD):
     def __init__(self, port = 0, baud = BAUD):
-        self._port = serial.Serial(port, baud, timeout=Uploader.TIMEOUT)
-        self.line_number = 0
-        self.verbose = False
-        self.debug = False
-
-
-    def set_verbose(self):
-        self.verbose = True
-
+        self._port = serial.Serial(port, Uploader.BAUD, timeout=Uploader.TIMEOUT)
+        if baud != Uploader.BAUD:
+            log.info('Changing communication to %s baud', baud)
+            self._port.write('uart.setup(0,%s,8,0,1,1)\r\n' % baud)
+            log.info(self.dump())
+            self._port.close()
+            self._port = serial.Serial(port, baud, timeout=Uploader.TIMEOUT)
 
 
-    def set_debug(self):
-        self.verbose = True
-        self.debug = True
+        self.line_number = 0
 
 
+    def close(self):
+        self._port.write('uart.setup(0,%s,8,0,1,1)\r\n' % Uploader.BAUD)
+        self._port.close()
 
 
     def dump(self, timeout=TIMEOUT):
     def dump(self, timeout=TIMEOUT):
         t = self._port.timeout
         t = self._port.timeout
@@ -88,20 +89,19 @@ class Uploader:
 
 
 
 
     def prepare(self):
     def prepare(self):
-        if self.verbose: log('Preparing esp for transfer.')
+        log.info('Preparing esp for transfer.')
         self.write_lines(save_lua.replace('9600', '%d' % self._port.baudrate))
         self.write_lines(save_lua.replace('9600', '%d' % self._port.baudrate))
         self._port.write('\r\n')
         self._port.write('\r\n')
-        if self.verbose: log('.')
+        
         d = self.dump(0.1)
         d = self.dump(0.1)
         if 'unexpected' in d or len(d) > len(save_lua)+10:
         if 'unexpected' in d or len(d) > len(save_lua)+10:
-            print 'error in save_lua', d
+            log.error('error in save_lua "%s"' % d)
             return
             return
-        if self.verbose: print('.done')
 
 
 
 
     def write(self, path):
     def write(self, path):
         filename = os.path.basename(path)
         filename = os.path.basename(path)
-        if self.verbose: log('Transfering %s' % filename)
+        log.info('Transfering %s' % filename)
         self.dump()
         self.dump()
         self._port.write(r"recv()" + '\n')
         self._port.write(r"recv()" + '\n')
 
 
@@ -110,19 +110,18 @@ class Uploader:
             time.sleep(1)
             time.sleep(1)
             count += 1
             count += 1
             if count > 5:
             if count > 5:
-                print 'Error waiting for esp', self.dump()
+                log.error('Error waiting for esp "%s"' % self.dump())
                 return
                 return
         self.dump(0.5)
         self.dump(0.5)
-        if self.verbose: log('.')
-        if self.debug: print 'sending filename', filename
+        log.debug('sending filename "%s"', filename)
         self._port.write(filename + '\x00')
         self._port.write(filename + '\x00')
 
 
         if not self.got_ack():
         if not self.got_ack():
-            print 'did not ack filename', self.dump()
+            log.error('did not ack filename: "%s"' % self.dump())
             return
             return
-        if self.verbose: log('.')
+
         f = open( path, 'rt' ); content = f.read(); f.close()
         f = open( path, 'rt' ); content = f.read(); f.close()
-        if self.debug: print 'sending %d bytes in %s' % (len(content), filename)
+        log.debug('sending %d bytes in %s' % (len(content), filename))
         pos = 0
         pos = 0
         chunk_size = 128
         chunk_size = 128
         error = False
         error = False
@@ -130,26 +129,22 @@ class Uploader:
             data = content[pos: pos+chunk_size]
             data = content[pos: pos+chunk_size]
             if not self.write_chunk(data):
             if not self.write_chunk(data):
                 error = True
                 error = True
-                print 'Bad send'
                 d = self.dump()
                 d = self.dump()
-                print d
-                print ':'.join(x.encode('hex') for x in d)
+                log.error('Bad chunk response "%s" %s' % (d, ':'.join(x.encode('hex') for x in d)))
                 break
                 break
 
 
             pos += chunk_size
             pos += chunk_size
             if pos + chunk_size > len(content):
             if pos + chunk_size > len(content):
                 chunk_size = len(content) - pos
                 chunk_size = len(content) - pos
             
             
-        if self.verbose: log('.')
-        if self.debug: print 'sending zero block'
+        log.debug('sending zero block')
         if not error:
         if not error:
             #zero size block
             #zero size block
             self.write_chunk('')
             self.write_chunk('')
-        if self.verbose: print 'done'
 
 
-    
+
     def got_ack(self):
     def got_ack(self):
-        if self.debug: print 'waiting for ack'
+        log.debug('waiting for ack')
         r = self._port.read(1)
         r = self._port.read(1)
         return r == '\x06' #ACK
         return r == '\x06' #ACK
 
 
@@ -160,24 +155,44 @@ class Uploader:
         for line in lines:
         for line in lines:
             self._port.write(line + '\r\n')
             self._port.write(line + '\r\n')
             d = self.dump(0.1)
             d = self.dump(0.1)
-            if self.debug: log(d)
+            log.debug(d)
         return
         return
 
 
 
 
     def write_chunk(self, chunk):
     def write_chunk(self, chunk):
-        if self.debug: print 'writing %d bytes chunk' % len(chunk)
+        log.debug('writing %d bytes chunk' % len(chunk))
         data = '\x01' + chr(len(chunk)) + chunk
         data = '\x01' + chr(len(chunk)) + chunk
         if len(chunk) < 128:
         if len(chunk) < 128:
             padding = 128 - len(chunk)
             padding = 128 - len(chunk)
-            if self.debug: print 'pad with %d characters' % padding
+            log.debug('pad with %d characters' % padding)
             data = data + (' ' * padding)
             data = data + (' ' * padding)
-        if self.debug: print "packet size %d" % len(data)
+        log.debug("packet size %d" % len(data))
         self._port.write(data)
         self._port.write(data)
 
 
         return self.got_ack()
         return self.got_ack()
         
         
 
 
-   
+    def file_list(self):
+        log.info('Listing files')
+        self._port.write('for key,value in pairs(file.list()) do print(key,value) end' + '\r\n')
+        r = self.dump()
+        log.info(r)
+        return r
+
+    def file_format(self):
+        log.info('Format')
+        self._port.write('file.format()' + '\r\n')
+        r = self.dump()
+        log.info(r)
+        return r
+
+    def node_heap(self):
+        log.info('Heap')
+        self._port.write('print(node.heap())\r\n')
+        r = self.dump()
+        log.info(r)
+        return r
+
 
 
 def arg_auto_int(x):
 def arg_auto_int(x):
     return int(x, 0)
     return int(x, 0)
@@ -192,7 +207,7 @@ if __name__ == '__main__':
 
 
     parser.add_argument(
     parser.add_argument(
             '--baud', '-b',
             '--baud', '-b',
-            help = 'Serial port baud rate',
+            help = 'Serial port baudrate',
             type = arg_auto_int,
             type = arg_auto_int,
             default = Uploader.BAUD)
             default = Uploader.BAUD)
 
 
@@ -202,25 +217,41 @@ if __name__ == '__main__':
             action = 'store_true',
             action = 'store_true',
             default = False)
             default = False)
 
 
-    parser.add_argument(
-            '--debug', '-d',
-            help = 'debug output',
-            action = 'store_true',
-            default = False)
+    subparsers = parser.add_subparsers(
+        dest='operation',
+        help = 'Run nodemcu-uploader {command} -h for additional help')
+
+    upload_parser = subparsers.add_parser(
+            'upload',
+            help = 'Upload file(s)')
 
 
-    parser.add_argument('filename',  nargs='+', help = 'Lua file to upload')
+    upload_parser.add_argument('filename',  nargs='+', help = 'Lua file to upload')
 
 
+    file_parser = subparsers.add_parser(
+        'file', 
+        help = 'File functions')
+
+    file_parser.add_argument('cmd', choices=('list', 'format'))
 
 
     args = parser.parse_args()
     args = parser.parse_args()
     
     
+    formatter = logging.Formatter('%(message)s')
+    logging.basicConfig(level=logging.INFO, format='%(message)s')
+    
     uploader = Uploader(args.port, args.baud)
     uploader = Uploader(args.port, args.baud)
     if args.verbose:
     if args.verbose:
-        uploader.set_verbose()
-    if args.debug:
-        uploader.set_debug()
-    
-    uploader.prepare()    
-    for f in args.filename:
-        uploader.write(f)
-    if args.verbose: 
-        print 'All done!' 
+        logger.setLevel(logging.DEBUG)
+
+    if args.operation == 'upload':
+        uploader.prepare()    
+        for f in args.filename:
+            uploader.write(f) 
+        print 'All done!'
+
+    elif args.operation == 'file':
+        if args.cmd == 'list': 
+            uploader.file_list()
+        elif args.cmd == 'format': 
+            uploader.file_format()
+
+    uploader.close()