From f095b4818cdf39bd4ff4c13ddcd44c942cd2661d Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Thu, 17 May 2018 16:13:30 +0200 Subject: [PATCH 1/2] Add python firmware server Python firmware server can provide binary OTA images to Tasmota. See README for usage. Tested on Linux. --- api/fw-server.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ api/fw/README | 3 ++ 2 files changed, 75 insertions(+) create mode 100644 api/fw-server.py create mode 100644 api/fw/README diff --git a/api/fw-server.py b/api/fw-server.py new file mode 100644 index 000000000..34f6c7270 --- /dev/null +++ b/api/fw-server.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 + +""" + fw-server.py - firmware server for Sonoff-Tasmota OTA upgrade + + Copyright (C) 2018 Gennaro Tortone + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Requirements: + - Python3 + - pip install netifaces flask + +Instructions: + Copy Sonoff-Tasmota firmware binary files in 'fw' directory. + A set of prebuilt files can be downloaded by Sonoff-Tasmota release page: + https://github.com/arendst/Sonoff-Tasmota/releases + + Configure your Sonoff-Tasmota device with your fw-server URL: + Firmware Upgrade -> Upgrade by web server + http://:5000/sonoff-minimal.bin + +Usage: + ./fw-server.py -d (default: eth0) + +Example: + ./fw-server.py -d wlan0 +""" + +import io +import os.path +from sys import exit +from flask import Flask, send_file +from optparse import OptionParser +import netifaces as ni + +parser = OptionParser() +parser.add_option("-d", "--dev", action="store", type="string", + dest="netdev", default="eth0", help="network interface (default: eth0)") +(options, args) = parser.parse_args() + +try: + netip = ni.ifaddresses(options.netdev)[ni.AF_INET][0]['addr'] +except Exception as e: + print("E: network interface error - {}".format(e)) + exit(1) + +app = Flask(__name__) + +@app.route('/') +def fw(filename): + if(os.path.exists("fw/" + str(filename))): + return send_file("fw/" + str(filename), attachment_filename=filename, mimetype='application/octet-stream') + else: + return("ERROR: file not found") + +if __name__ == "__main__": + try: + app.run(host=netip) + except Exception as e: + print("E: {}".format(e)) \ No newline at end of file diff --git a/api/fw/README b/api/fw/README new file mode 100644 index 000000000..c29367442 --- /dev/null +++ b/api/fw/README @@ -0,0 +1,3 @@ +Copy Sonoff-Tasmota firmware binary files in this directory. +A set of prebuilt files can be downloaded by Sonoff-Tasmota release page: +https://github.com/arendst/Sonoff-Tasmota/releases \ No newline at end of file From 0356a90805d4372ba0e934c91d9b70aa5ab80e2f Mon Sep 17 00:00:00 2001 From: Gennaro Tortone Date: Thu, 17 May 2018 18:03:02 +0200 Subject: [PATCH 2/2] fw-server: add ip option --- api/fw-server.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) mode change 100644 => 100755 api/fw-server.py diff --git a/api/fw-server.py b/api/fw-server.py old mode 100644 new mode 100755 index 34f6c7270..867d89709 --- a/api/fw-server.py +++ b/api/fw-server.py @@ -33,9 +33,13 @@ Instructions: Usage: ./fw-server.py -d (default: eth0) + or + ./fw-server.py -i Example: - ./fw-server.py -d wlan0 + ./fw-server.py -d wlan0 + or + ./fw-server.py -i 192.168.1.10 """ import io @@ -45,16 +49,23 @@ from flask import Flask, send_file from optparse import OptionParser import netifaces as ni -parser = OptionParser() + +usage = "usage: fw-server {-d | -i} arg" +parser = OptionParser(usage) parser.add_option("-d", "--dev", action="store", type="string", dest="netdev", default="eth0", help="network interface (default: eth0)") +parser.add_option("-i", "--ip", action="store", type="string", + dest="ip", help="IP address to bind") (options, args) = parser.parse_args() -try: - netip = ni.ifaddresses(options.netdev)[ni.AF_INET][0]['addr'] -except Exception as e: - print("E: network interface error - {}".format(e)) - exit(1) +if options.ip is None: + try: + netip = ni.ifaddresses(options.netdev)[ni.AF_INET][0]['addr'] + except Exception as e: + print("E: network interface error - {}".format(e)) + exit(1) +else: + netip = options.ip app = Flask(__name__) @@ -69,4 +80,4 @@ if __name__ == "__main__": try: app.run(host=netip) except Exception as e: - print("E: {}".format(e)) \ No newline at end of file + print("E: {}".format(e))