Browse Source

Merge remote-tracking branch 'origin/dev' into compact-ws

sensors
Max Prokhorov 5 years ago
parent
commit
3e121edf3a
28 changed files with 18264 additions and 18050 deletions
  1. +1
    -0
      code/espurna/config/all.h
  2. +2
    -0
      code/espurna/config/arduino.h
  3. +9
    -0
      code/espurna/config/deprecated.h
  4. +5
    -0
      code/espurna/config/general.h
  5. +22
    -0
      code/espurna/config/hardware.h
  6. BIN
      code/espurna/data/index.all.html.gz
  7. BIN
      code/espurna/data/index.light.html.gz
  8. BIN
      code/espurna/data/index.rfbridge.html.gz
  9. BIN
      code/espurna/data/index.rfm69.html.gz
  10. BIN
      code/espurna/data/index.sensor.html.gz
  11. BIN
      code/espurna/data/index.small.html.gz
  12. +20
    -2
      code/espurna/domoticz.ino
  13. +11
    -0
      code/espurna/migrate.ino
  14. +5
    -0
      code/espurna/relay.ino
  15. +7
    -1
      code/espurna/sensors/PMSX003Sensor.h
  16. +3145
    -3133
      code/espurna/static/index.all.html.gz.h
  17. +2997
    -2985
      code/espurna/static/index.light.html.gz.h
  18. +2602
    -2590
      code/espurna/static/index.rfbridge.html.gz.h
  19. +4079
    -4067
      code/espurna/static/index.rfm69.html.gz.h
  20. +2660
    -2648
      code/espurna/static/index.sensor.html.gz.h
  21. +2557
    -2545
      code/espurna/static/index.small.html.gz.h
  22. +9
    -1
      code/espurna/utils.ino
  23. +2
    -0
      code/espurna/ws.ino
  24. +11
    -0
      code/html/index.html
  25. +27
    -25
      code/memanalyzer.py
  26. +56
    -45
      code/ota.py
  27. +26
    -1
      code/platformio.ini
  28. +11
    -7
      pre-commit

+ 1
- 0
code/espurna/config/all.h View File

@ -28,6 +28,7 @@
#include "arduino.h" #include "arduino.h"
#include "hardware.h" #include "hardware.h"
#include "defaults.h" #include "defaults.h"
#include "deprecated.h"
#include "general.h" #include "general.h"
#include "dependencies.h" #include "dependencies.h"
#include "debug.h" #include "debug.h"


+ 2
- 0
code/espurna/config/arduino.h View File

@ -41,6 +41,7 @@
//#define ELECTRODRAGON_WIFI_IOT //#define ELECTRODRAGON_WIFI_IOT
//#define WORKCHOICE_ECOPLUG //#define WORKCHOICE_ECOPLUG
//#define AITHINKER_AI_LIGHT //#define AITHINKER_AI_LIGHT
//#define LYASI_LIGHT
//#define MAGICHOME_LED_CONTROLLER //#define MAGICHOME_LED_CONTROLLER
//#define MAGICHOME_LED_CONTROLLER_20 //#define MAGICHOME_LED_CONTROLLER_20
//#define HUACANXING_H801 //#define HUACANXING_H801
@ -112,6 +113,7 @@
//#define SMARTLIFE_MINI_SMART_SOCKET //#define SMARTLIFE_MINI_SMART_SOCKET
//#define GOSUND_SP1_V23 //#define GOSUND_SP1_V23
//#define ARILUX_AL_LC02_V14 //#define ARILUX_AL_LC02_V14
//#define BLITZWOLF_BWSHP2_V23
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Features (values below are non-default values) // Features (values below are non-default values)


+ 9
- 0
code/espurna/config/deprecated.h View File

@ -0,0 +1,9 @@
#pragma once
// 1.13.3 added TELNET_PASSWORD build-only flag
// 1.13.4 replaces it with TELNET_AUTHENTICATION runtime setting default
// TODO warning should be removed eventually
#ifdef TELNET_PASSWORD
#warning TELNET_PASSWORD is deprecated! Please replace it with TELNET_AUTHENTICATION
#define TELNET_AUTHENTICATION TELNET_PASSWORD
#endif

+ 5
- 0
code/espurna/config/general.h View File

@ -235,6 +235,10 @@
#define HEARTBEAT_REPORT_HOSTNAME 1 #define HEARTBEAT_REPORT_HOSTNAME 1
#endif #endif
#ifndef HEARTBEAT_REPORT_DESCRITION
#define HEARTBEAT_REPORT_DESCRITION 1
#endif
#ifndef HEARTBEAT_REPORT_APP #ifndef HEARTBEAT_REPORT_APP
#define HEARTBEAT_REPORT_APP 1 #define HEARTBEAT_REPORT_APP 1
#endif #endif
@ -802,6 +806,7 @@
#define MQTT_TOPIC_APP "app" #define MQTT_TOPIC_APP "app"
#define MQTT_TOPIC_INTERVAL "interval" #define MQTT_TOPIC_INTERVAL "interval"
#define MQTT_TOPIC_HOSTNAME "host" #define MQTT_TOPIC_HOSTNAME "host"
#define MQTT_TOPIC_DESCRIPTION "desc"
#define MQTT_TOPIC_TIME "time" #define MQTT_TOPIC_TIME "time"
#define MQTT_TOPIC_RFOUT "rfout" #define MQTT_TOPIC_RFOUT "rfout"
#define MQTT_TOPIC_RFIN "rfin" #define MQTT_TOPIC_RFIN "rfin"


+ 22
- 0
code/espurna/config/hardware.h View File

@ -1151,6 +1151,28 @@
#define MY92XX_COMMAND MY92XX_COMMAND_DEFAULT #define MY92XX_COMMAND MY92XX_COMMAND_DEFAULT
#define MY92XX_MAPPING 0, 1, 2, 3 #define MY92XX_MAPPING 0, 1, 2, 3
// -----------------------------------------------------------------------------
// Lyasi LED
// -----------------------------------------------------------------------------
#elif defined(LYASI_LIGHT)
// Info
#define MANUFACTURER "LYASI"
#define DEVICE "RGB-LED"
#define RELAY_PROVIDER RELAY_PROVIDER_LIGHT
#define LIGHT_PROVIDER LIGHT_PROVIDER_MY92XX
#define DUMMY_RELAY_COUNT 1
// Light
#define LIGHT_CHANNELS 4
#define MY92XX_MODEL MY92XX_MODEL_MY9291
#define MY92XX_CHIPS 1
#define MY92XX_DI_PIN 4
#define MY92XX_DCKI_PIN 5
#define MY92XX_COMMAND MY92XX_COMMAND_DEFAULT
#define MY92XX_MAPPING 0, 1, 2, 3
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// LED Controller // LED Controller
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------


BIN
code/espurna/data/index.all.html.gz View File


BIN
code/espurna/data/index.light.html.gz View File


BIN
code/espurna/data/index.rfbridge.html.gz View File


BIN
code/espurna/data/index.rfm69.html.gz View File


BIN
code/espurna/data/index.sensor.html.gz View File


BIN
code/espurna/data/index.small.html.gz View File


+ 20
- 2
code/espurna/domoticz.ino View File

@ -11,6 +11,7 @@ Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
#include <ArduinoJson.h> #include <ArduinoJson.h>
bool _dcz_enabled = false; bool _dcz_enabled = false;
std::vector<bool> _dcz_relay_state;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Private methods // Private methods
@ -36,6 +37,15 @@ void _domoticzMqttSubscribe(bool value) {
} }
bool _domoticzStatus(unsigned char id) {
return _dcz_relay_state[id];
}
void _domoticzStatus(unsigned char id, bool status) {
_dcz_relay_state[id] = status;
relayStatus(id, status);
}
void _domoticzMqtt(unsigned int type, const char * topic, const char * payload) { void _domoticzMqtt(unsigned int type, const char * topic, const char * payload) {
if (!_dcz_enabled) return; if (!_dcz_enabled) return;
@ -128,7 +138,7 @@ void _domoticzMqtt(unsigned int type, const char * topic, const char * payload)
if (relayID >= 0) { if (relayID >= 0) {
unsigned char value = root["nvalue"]; unsigned char value = root["nvalue"];
DEBUG_MSG_P(PSTR("[DOMOTICZ] Received value %u for IDX %u\n"), value, idx); DEBUG_MSG_P(PSTR("[DOMOTICZ] Received value %u for IDX %u\n"), value, idx);
relayStatus(relayID, value > 0);
_domoticzStatus(relayID, value > 0);
} }
} }
#else #else
@ -139,7 +149,7 @@ void _domoticzMqtt(unsigned int type, const char * topic, const char * payload)
if (relayID >= 0) { if (relayID >= 0) {
unsigned char value = root["nvalue"]; unsigned char value = root["nvalue"];
DEBUG_MSG_P(PSTR("[DOMOTICZ] Received value %u for IDX %u\n"), value, idx); DEBUG_MSG_P(PSTR("[DOMOTICZ] Received value %u for IDX %u\n"), value, idx);
relayStatus(relayID, value == 1);
_domoticzStatus(relayID, value == 1);
} }
} }
@ -196,6 +206,12 @@ void _domoticzWebSocketOnSend(JsonObject& root) {
void _domoticzConfigure() { void _domoticzConfigure() {
bool enabled = getSetting("dczEnabled", DOMOTICZ_ENABLED).toInt() == 1; bool enabled = getSetting("dczEnabled", DOMOTICZ_ENABLED).toInt() == 1;
if (enabled != _dcz_enabled) _domoticzMqttSubscribe(enabled); if (enabled != _dcz_enabled) _domoticzMqttSubscribe(enabled);
_dcz_relay_state.reserve(relayCount());
for (size_t n = 0; n < relayCount(); ++n) {
_dcz_relay_state[n] = relayStatus(n);
}
_dcz_enabled = enabled; _dcz_enabled = enabled;
} }
@ -219,6 +235,8 @@ template<typename T> void domoticzSend(const char * key, T nvalue) {
void domoticzSendRelay(unsigned char relayID, bool status) { void domoticzSendRelay(unsigned char relayID, bool status) {
if (!_dcz_enabled) return; if (!_dcz_enabled) return;
if (_domoticzStatus(relayID) == status) return;
_dcz_relay_state[relayID] = status;
char buffer[15]; char buffer[15];
snprintf_P(buffer, sizeof(buffer), PSTR("dczRelayIdx%u"), relayID); snprintf_P(buffer, sizeof(buffer), PSTR("dczRelayIdx%u"), relayID);
domoticzSend(buffer, status ? "1" : "0"); domoticzSend(buffer, status ? "1" : "0");


+ 11
- 0
code/espurna/migrate.ino View File

@ -257,6 +257,17 @@ void migrate() {
setSetting("myDCKIGPIO", 15); setSetting("myDCKIGPIO", 15);
setSetting("relays", 1); setSetting("relays", 1);
#elif defined(LYASI_LIGHT)
setSetting("board", 20);
setSetting("relayProvider", RELAY_PROVIDER_LIGHT);
setSetting("lightProvider", LIGHT_PROVIDER_MY92XX);
setSetting("myModel", MY92XX_MODEL_MY9291);
setSetting("myChips", 1);
setSetting("myDIGPIO", 4);
setSetting("myDCKIGPIO", 5);
setSetting("relays", 1);
#elif defined(MAGICHOME_LED_CONTROLLER) #elif defined(MAGICHOME_LED_CONTROLLER)
setSetting("board", 21); setSetting("board", 21);


+ 5
- 0
code/espurna/relay.ino View File

@ -83,6 +83,11 @@ void _relayProviderStatus(unsigned char id, bool status) {
Serial.write(id + 1); Serial.write(id + 1);
Serial.write(status); Serial.write(status);
Serial.write(0xA1 + status + id); Serial.write(0xA1 + status + id);
// The serial init are not full recognized by relais board.
// References: https://github.com/xoseperez/espurna/issues/1519 , https://github.com/xoseperez/espurna/issues/1130
delay(100);
Serial.flush(); Serial.flush();
#endif #endif


+ 7
- 1
code/espurna/sensors/PMSX003Sensor.h View File

@ -22,6 +22,7 @@
#define PMS_TYPE_X003_9 1 #define PMS_TYPE_X003_9 1
#define PMS_TYPE_5003T 2 #define PMS_TYPE_5003T 2
#define PMS_TYPE_5003ST 3 #define PMS_TYPE_5003ST 3
#define PMS_TYPE_5003S 4
// Sensor type specified data // Sensor type specified data
#define PMS_SLOT_MAX 4 #define PMS_SLOT_MAX 4
@ -35,7 +36,8 @@ const static struct {
{"PMSX003", 13, 3, {MAGNITUDE_PM1dot0, MAGNITUDE_PM2dot5, MAGNITUDE_PM10}}, {"PMSX003", 13, 3, {MAGNITUDE_PM1dot0, MAGNITUDE_PM2dot5, MAGNITUDE_PM10}},
{"PMSX003_9", 9, 3, {MAGNITUDE_PM1dot0, MAGNITUDE_PM2dot5, MAGNITUDE_PM10}}, {"PMSX003_9", 9, 3, {MAGNITUDE_PM1dot0, MAGNITUDE_PM2dot5, MAGNITUDE_PM10}},
{"PMS5003T", 13, 3, {MAGNITUDE_PM2dot5, MAGNITUDE_TEMPERATURE, MAGNITUDE_HUMIDITY}}, {"PMS5003T", 13, 3, {MAGNITUDE_PM2dot5, MAGNITUDE_TEMPERATURE, MAGNITUDE_HUMIDITY}},
{"PMS5003ST", 17, 4, {MAGNITUDE_PM2dot5, MAGNITUDE_TEMPERATURE, MAGNITUDE_HUMIDITY, MAGNITUDE_HCHO}}
{"PMS5003ST", 17, 4, {MAGNITUDE_PM2dot5, MAGNITUDE_TEMPERATURE, MAGNITUDE_HUMIDITY, MAGNITUDE_HCHO}},
{"PMS5003S", 13, 3, {MAGNITUDE_PM2dot5, MAGNITUDE_PM10, MAGNITUDE_HCHO}},
}; };
// [MAGIC][LEN][DATA9|13|17][SUM] // [MAGIC][LEN][DATA9|13|17][SUM]
@ -306,6 +308,10 @@ class PMSX003Sensor : public BaseSensor, PMSX003 {
_slot_values[1] = (double)data[13] / 10; _slot_values[1] = (double)data[13] / 10;
_slot_values[2] = (double)data[14] / 10; _slot_values[2] = (double)data[14] / 10;
_slot_values[3] = (double)data[12] / 1000; _slot_values[3] = (double)data[12] / 1000;
} else if (_type == PMS_TYPE_5003S) {
_slot_values[0] = data[4];
_slot_values[1] = data[5];
_slot_values[2] = (double)data[12] / 1000;
} else if (_type == PMS_TYPE_5003T) { } else if (_type == PMS_TYPE_5003T) {
_slot_values[0] = data[4]; _slot_values[0] = data[4];
_slot_values[1] = (double)data[10] / 10; _slot_values[1] = (double)data[10] / 10;


+ 3145
- 3133
code/espurna/static/index.all.html.gz.h
File diff suppressed because it is too large
View File


+ 2997
- 2985
code/espurna/static/index.light.html.gz.h
File diff suppressed because it is too large
View File


+ 2602
- 2590
code/espurna/static/index.rfbridge.html.gz.h
File diff suppressed because it is too large
View File


+ 4079
- 4067
code/espurna/static/index.rfm69.html.gz.h
File diff suppressed because it is too large
View File


+ 2660
- 2648
code/espurna/static/index.sensor.html.gz.h
File diff suppressed because it is too large
View File


+ 2557
- 2545
code/espurna/static/index.small.html.gz.h
File diff suppressed because it is too large
View File


+ 9
- 1
code/espurna/utils.ino View File

@ -164,7 +164,8 @@ namespace Heartbeat {
Version = 1 << 14, Version = 1 << 14,
Board = 1 << 15, Board = 1 << 15,
Loadavg = 1 << 16, Loadavg = 1 << 16,
Interval = 1 << 17
Interval = 1 << 17,
Description = 1 << 18
}; };
constexpr uint32_t defaultValue() { constexpr uint32_t defaultValue() {
@ -180,6 +181,7 @@ namespace Heartbeat {
(Relay * (HEARTBEAT_REPORT_RELAY)) | \ (Relay * (HEARTBEAT_REPORT_RELAY)) | \
(Light * (HEARTBEAT_REPORT_LIGHT)) | \ (Light * (HEARTBEAT_REPORT_LIGHT)) | \
(Hostname * (HEARTBEAT_REPORT_HOSTNAME)) | \ (Hostname * (HEARTBEAT_REPORT_HOSTNAME)) | \
(Description * (HEARTBEAT_REPORT_DESCRITION)) | \
(App * (HEARTBEAT_REPORT_APP)) | \ (App * (HEARTBEAT_REPORT_APP)) | \
(Version * (HEARTBEAT_REPORT_VERSION)) | \ (Version * (HEARTBEAT_REPORT_VERSION)) | \
(Board * (HEARTBEAT_REPORT_BOARD)) | \ (Board * (HEARTBEAT_REPORT_BOARD)) | \
@ -247,6 +249,12 @@ void heartbeat() {
if (hb_cfg & Heartbeat::Hostname) if (hb_cfg & Heartbeat::Hostname)
mqttSend(MQTT_TOPIC_HOSTNAME, getSetting("hostname", getIdentifier()).c_str()); mqttSend(MQTT_TOPIC_HOSTNAME, getSetting("hostname", getIdentifier()).c_str());
if (hb_cfg & Heartbeat::Description) {
if (hasSetting("desc")) {
mqttSend(MQTT_TOPIC_DESCRIPTION, getSetting("desc").c_str());
}
}
if (hb_cfg & Heartbeat::Ssid) if (hb_cfg & Heartbeat::Ssid)
mqttSend(MQTT_TOPIC_SSID, WiFi.SSID().c_str()); mqttSend(MQTT_TOPIC_SSID, WiFi.SSID().c_str());


+ 2
- 0
code/espurna/ws.ino View File

@ -328,6 +328,7 @@ bool _wsOnReceive(const char * key, JsonVariant& value) {
if (strncmp(key, "ws", 2) == 0) return true; if (strncmp(key, "ws", 2) == 0) return true;
if (strncmp(key, "admin", 5) == 0) return true; if (strncmp(key, "admin", 5) == 0) return true;
if (strncmp(key, "hostname", 8) == 0) return true; if (strncmp(key, "hostname", 8) == 0) return true;
if (strncmp(key, "desc", 4) == 0) return true;
if (strncmp(key, "webPort", 7) == 0) return true; if (strncmp(key, "webPort", 7) == 0) return true;
return false; return false;
} }
@ -357,6 +358,7 @@ void _wsOnStart(JsonObject& root) {
root["channel"] = WiFi.channel(); root["channel"] = WiFi.channel();
root["device"] = DEVICE; root["device"] = DEVICE;
root["hostname"] = getSetting("hostname"); root["hostname"] = getSetting("hostname");
root["desc"] = getSetting("desc");
root["network"] = getNetwork(); root["network"] = getNetwork();
root["deviceip"] = getIP(); root["deviceip"] = getIP();
root["sketch_size"] = ESP.getSketchSize(); root["sketch_size"] = ESP.getSketchSize();


+ 11
- 0
code/html/index.html View File

@ -84,6 +84,7 @@
<span class="pure-menu-heading" name="hostname">HOSTNAME</span> <span class="pure-menu-heading" name="hostname">HOSTNAME</span>
<span class="pure-menu-heading small" name="title">ESPurna 0.0.0</span> <span class="pure-menu-heading small" name="title">ESPurna 0.0.0</span>
<span class="pure-menu-heading small" name="desc"></span>
<ul class="pure-menu-list"> <ul class="pure-menu-list">
@ -342,6 +343,16 @@
</div> </div>
</div> </div>
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Description</label>
<input name="desc" class="pure-u-1 pure-u-lg-3-4" maxlength="64" type="text" tabindex="2" />
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4 hint">
Human-friendly name for your device. Will be reported with the heartbeat.<br />
You can use this to specify the location or some other identification information.
</div>
</div>
<div class="pure-g"> <div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Double click delay</label> <label class="pure-u-1 pure-u-lg-1-4">Double click delay</label>
<input name="btnDelay" class="pure-u-1 pure-u-lg-1-4" type="number" action="reboot" min="0" step="100" max="1000" tabindex="6" /> <input name="btnDelay" class="pure-u-1 pure-u-lg-1-4" type="number" action="reboot" min="0" step="100" max="1000" tabindex="6" />


+ 27
- 25
code/memanalyzer.py View File

@ -19,15 +19,16 @@ import argparse
import os import os
import re import re
import shlex import shlex
import subprocess
import sys import sys
from collections import OrderedDict from collections import OrderedDict
from sortedcontainers import SortedDict from sortedcontainers import SortedDict
import subprocess
if (sys.version_info > (3, 0)):
from subprocess import getstatusoutput as getstatusoutput
if sys.version_info > (3, 0):
from subprocess import getstatusoutput
else: else:
from commands import getstatusoutput as getstatusoutput
from commands import getstatusoutput
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
@ -55,7 +56,7 @@ def file_size(file):
def analyse_memory(elf_file): def analyse_memory(elf_file):
command = "%s -t '%s'" % (objdump_binary, elf_file)
command = "{} -t '{}'".format(objdump_binary, elf_file)
response = subprocess.check_output(shlex.split(command)) response = subprocess.check_output(shlex.split(command))
if isinstance(response, bytes): if isinstance(response, bytes):
response = response.decode('utf-8') response = response.decode('utf-8')
@ -66,8 +67,8 @@ def analyse_memory(elf_file):
ret = {} ret = {}
for (id_, _) in list(sections.items()): for (id_, _) in list(sections.items()):
section_start_token = " _%s_start" % id_
section_end_token = " _%s_end" % id_
section_start_token = " _{}_start".format(id_)
section_end_token = " _{}_end".format(id_)
section_start = -1 section_start = -1
section_end = -1 section_end = -1
for line in lines: for line in lines:
@ -92,24 +93,26 @@ def analyse_memory(elf_file):
# print("{0: >10}|{1: >30}|{2:12X}|{3:12X}|{4:8}".format(id_, descr, section_start, section_end, section_length)) # print("{0: >10}|{1: >30}|{2:12X}|{3:12X}|{4:8}".format(id_, descr, section_start, section_end, section_length))
# i += 1 # i += 1
# print("Total Used RAM : %d" % usedRAM)
# print("Free RAM : %d" % (TOTAL_DRAM - usedRAM))
# print("Free IRam : %d" % usedIRAM)
# print("Total Used RAM : {:d}".format(usedRAM))
# print("Free RAM : {:d}".format(TOTAL_DRAM - usedRAM))
# print("Free IRam : {:d}".format(usedIRAM))
return ret return ret
def run(env_, modules_): def run(env_, modules_):
flags = "" flags = ""
for item in modules_.items():
flags += "-D%s_SUPPORT=%d " % item
command = "ESPURNA_BOARD=\"WEMOS_D1_MINI_RELAYSHIELD\" ESPURNA_FLAGS=\"%s\" platformio run --silent --environment %s 2>/dev/null" % (flags, env_)
for k, v in modules_.items():
flags += "-D{}_SUPPORT={:d} ".format(k, v)
command = "ESPURNA_BOARD=\"WEMOS_D1_MINI_RELAYSHIELD\" ESPURNA_FLAGS=\"{}\" platformio run --silent --environment {} 2>/dev/null".format(flags, env_)
subprocess.check_call(command, shell=True) subprocess.check_call(command, shell=True)
def calc_free(module): def calc_free(module):
free = 80 * 1024 - module['data'] - module['rodata'] - module['bss'] free = 80 * 1024 - module['data'] - module['rodata'] - module['bss']
free = free + (16 - free % 16) free = free + (16 - free % 16)
module['free'] = free module['free'] = free
def modules_get(): def modules_get():
modules_ = SortedDict() modules_ = SortedDict()
for line in open("espurna/config/arduino.h"): for line in open("espurna/config/arduino.h"):
@ -120,7 +123,8 @@ def modules_get():
del modules_['NETBIOS'] del modules_['NETBIOS']
return modules_ return modules_
try:
if __name__ == '__main__':
# Parse command line options # Parse command line options
parser = argparse.ArgumentParser(description=description) parser = argparse.ArgumentParser(description=description)
@ -160,7 +164,7 @@ try:
# Check test modules exist # Check test modules exist
for module in test_modules: for module in test_modules:
if module not in available_modules: if module not in available_modules:
print("Module %s not found" % module)
print("Module {} not found".format(module))
sys.exit(2) sys.exit(2)
# Define base configuration # Define base configuration
@ -173,9 +177,9 @@ try:
# Show init message # Show init message
if len(test_modules) > 0: if len(test_modules) > 0:
print("Analyzing module(s) %s on top of %s configuration\n" % (", ".join(test_modules), "CORE" if args.core > 0 else "DEFAULT"))
print("Analyzing module(s) {} on top of {} configuration\n".format(", ".join(test_modules), "CORE" if args.core > 0 else "DEFAULT"))
else: else:
print("Analyzing %s configuration\n" % ("CORE" if args.core > 0 else "DEFAULT"))
print("Analyzing {} configuration\n".format("CORE" if args.core > 0 else "DEFAULT"))
output_format = "{:<20}|{:<15}|{:<15}|{:<15}|{:<15}|{:<15}|{:<15}|{:<15}" output_format = "{:<20}|{:<15}|{:<15}|{:<15}|{:<15}|{:<15}|{:<15}|{:<15}"
print(output_format.format( print(output_format.format(
@ -211,8 +215,8 @@ try:
# Build the core without modules to get base memory usage # Build the core without modules to get base memory usage
run(env, modules) run(env, modules)
base = analyse_memory(".pioenvs/%s/firmware.elf" % env)
base['size'] = file_size(".pioenvs/%s/firmware.bin" % env)
base = analyse_memory(".pioenvs/{}/firmware.elf".format(env))
base['size'] = file_size(".pioenvs/{}/firmware.bin".format(env))
calc_free(base) calc_free(base)
print(output_format.format( print(output_format.format(
"CORE" if args.core == 1 else "DEFAULT", "CORE" if args.core == 1 else "DEFAULT",
@ -231,8 +235,8 @@ try:
modules[module] = 1 modules[module] = 1
run(env, modules) run(env, modules)
results[module] = analyse_memory(".pioenvs/%s/firmware.elf" % env)
results[module]['size'] = file_size(".pioenvs/%s/firmware.bin" % env)
results[module] = analyse_memory(".pioenvs/{}/firmware.elf".format(env))
results[module]['size'] = file_size(".pioenvs/{}/firmware.bin".format(env))
calc_free(results[module]) calc_free(results[module])
modules[module] = 0 modules[module] = 0
@ -253,8 +257,8 @@ try:
for module in test_modules: for module in test_modules:
modules[module] = 1 modules[module] = 1
run(env, modules) run(env, modules)
total = analyse_memory(".pioenvs/%s/firmware.elf" % env)
total['size'] = file_size(".pioenvs/%s/firmware.bin" % env)
total = analyse_memory(".pioenvs/{}/firmware.elf".format(env))
total['size'] = file_size(".pioenvs/{}/firmware.bin".format(env))
calc_free(total) calc_free(total)
if len(test_modules) > 1: if len(test_modules) > 1:
@ -279,7 +283,5 @@ try:
total['size'], total['size'],
)) ))
except:
raise
print("\n") print("\n")

+ 56
- 45
code/ota.py View File

@ -8,14 +8,14 @@
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
from __future__ import print_function from __future__ import print_function
import shutil
import argparse import argparse
import os
import re import re
import shutil
import socket import socket
import subprocess import subprocess
import sys import sys
import time import time
import os
from zeroconf import ServiceBrowser, ServiceStateChange, Zeroconf from zeroconf import ServiceBrowser, ServiceStateChange, Zeroconf
@ -33,6 +33,7 @@ description = "ESPurna OTA Manager v0.3"
devices = [] devices = []
discover_last = 0 discover_last = 0
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
def on_service_state_change(zeroconf, service_type, name, state_change): def on_service_state_change(zeroconf, service_type, name, state_change):
@ -61,7 +62,7 @@ def on_service_state_change(zeroconf, service_type, name, state_change):
} }
for key, item in info.properties.items(): for key, item in info.properties.items():
device[key.decode('UTF-8')] = item.decode('UTF-8');
device[key.decode('UTF-8')] = item.decode('UTF-8')
# rename fields (needed for sorting by name) # rename fields (needed for sorting by name)
device['app'] = device['app_name'] device['app'] = device['app_name']
@ -75,35 +76,35 @@ def list_devices():
""" """
Shows the list of discovered devices Shows the list of discovered devices
""" """
output_format="{:>3} {:<14} {:<15} {:<17} {:<12} {:<12} {:<25} {:<8} {:<8} {:<10}"
output_format = "{:>3} {:<14} {:<15} {:<17} {:<12} {:<12} {:<25} {:<8} {:<8} {:<10}"
print(output_format.format( print(output_format.format(
"#",
"HOSTNAME",
"IP",
"MAC",
"APP",
"VERSION",
"DEVICE",
"MEM_SIZE",
"SDK_SIZE",
"FREE_SPACE"
"#",
"HOSTNAME",
"IP",
"MAC",
"APP",
"VERSION",
"DEVICE",
"MEM_SIZE",
"SDK_SIZE",
"FREE_SPACE"
)) ))
print("-" * 139) print("-" * 139)
index = 0 index = 0
for device in devices: for device in devices:
index = index + 1
index += 1
print(output_format.format( print(output_format.format(
index,
device.get('hostname', ''),
device.get('ip', ''),
device.get('mac', ''),
device.get('app_name', ''),
device.get('app_version', ''),
device.get('target_board', ''),
device.get('mem_size', 0),
device.get('sdk_size', 0),
device.get('free_space', 0),
index,
device.get('hostname', ''),
device.get('ip', ''),
device.get('mac', ''),
device.get('app_name', ''),
device.get('app_version', ''),
device.get('target_board', ''),
device.get('mem_size', 0),
device.get('sdk_size', 0),
device.get('free_space', 0),
)) ))
print() print()
@ -120,11 +121,13 @@ def get_boards():
boards.append(m.group(1)) boards.append(m.group(1))
return sorted(boards) return sorted(boards)
def get_device_size(device): def get_device_size(device):
if device.get('mem_size', 0) == device.get('sdk_size', 0): if device.get('mem_size', 0) == device.get('sdk_size', 0):
return int(device.get('mem_size', 0)) / 1024 return int(device.get('mem_size', 0)) / 1024
return 0 return 0
def get_empty_board(): def get_empty_board():
""" """
Returns the empty structure of a board to flash Returns the empty structure of a board to flash
@ -132,12 +135,13 @@ def get_empty_board():
board = {'board': '', 'ip': '', 'size': 0, 'auth': '', 'flags': ''} board = {'board': '', 'ip': '', 'size': 0, 'auth': '', 'flags': ''}
return board return board
def get_board_by_index(index): def get_board_by_index(index):
""" """
Returns the required data to flash a given board Returns the required data to flash a given board
""" """
board = {} board = {}
if 1 <= index and index <= len(devices):
if 1 <= index <= len(devices):
device = devices[index - 1] device = devices[index - 1]
board['hostname'] = device.get('hostname') board['hostname'] = device.get('hostname')
board['board'] = device.get('target_board', '') board['board'] = device.get('target_board', '')
@ -145,6 +149,7 @@ def get_board_by_index(index):
board['size'] = get_device_size(device) board['size'] = get_device_size(device)
return board return board
def get_board_by_mac(mac): def get_board_by_mac(mac):
""" """
Returns the required data to flash a given board Returns the required data to flash a given board
@ -161,6 +166,7 @@ def get_board_by_mac(mac):
return board return board
return None return None
def get_board_by_hostname(hostname): def get_board_by_hostname(hostname):
""" """
Returns the required data to flash a given board Returns the required data to flash a given board
@ -178,6 +184,7 @@ def get_board_by_hostname(hostname):
return board return board
return None return None
def input_board(): def input_board():
""" """
Grabs info from the user about what device to flash Grabs info from the user about what device to flash
@ -189,10 +196,10 @@ def input_board():
except ValueError: except ValueError:
index = 0 index = 0
if index < 0 or len(devices) < index: if index < 0 or len(devices) < index:
print("Board number must be between 1 and %s\n" % str(len(devices)))
print("Board number must be between 1 and {}\n".format(str(len(devices))))
return None return None
board = get_board_by_index(index);
board = get_board_by_index(index)
# Choose board type if none before # Choose board type if none before
if len(board.get('board', '')) == 0: if len(board.get('board', '')) == 0:
@ -201,15 +208,15 @@ def input_board():
count = 1 count = 1
boards = get_boards() boards = get_boards()
for name in boards: for name in boards:
print("%3d\t%s" % (count, name))
count = count + 1
print("{:3d}\t{}".format(count, name))
count += 1
print() print()
try: try:
index = int(input("Choose the board type you want to flash: ")) index = int(input("Choose the board type you want to flash: "))
except ValueError: except ValueError:
index = 0 index = 0
if index < 1 or len(boards) < index: if index < 1 or len(boards) < index:
print("Board number must be between 1 and %s\n" % str(len(boards)))
print("Board number must be between 1 and {}\n".format(str(len(boards))))
return None return None
board['board'] = boards[index - 1] board['board'] = boards[index - 1]
@ -227,12 +234,14 @@ def input_board():
return board return board
def boardname(board): def boardname(board):
return board.get('hostname', board['ip']) return board.get('hostname', board['ip'])
def store(device, env): def store(device, env):
source = ".pioenvs/%s/firmware.elf" % env
destination = ".pioenvs/elfs/%s.elf" % boardname(device).lower()
source = ".pioenvs/{}/firmware.elf".format(env)
destination = ".pioenvs/elfs/{}.elf".format(boardname(device).lower())
dst_dir = os.path.dirname(destination) dst_dir = os.path.dirname(destination)
if not os.path.exists(dst_dir): if not os.path.exists(dst_dir):
@ -240,6 +249,7 @@ def store(device, env):
shutil.move(source, destination) shutil.move(source, destination)
def run(device, env): def run(device, env):
print("Building and flashing image over-the-air...") print("Building and flashing image over-the-air...")
environ = os.environ.copy() environ = os.environ.copy()
@ -253,6 +263,7 @@ def run(device, env):
store(device, env) store(device, env)
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
if __name__ == '__main__': if __name__ == '__main__':
@ -272,13 +283,13 @@ if __name__ == '__main__':
print(description) print(description)
print() print()
# Look for sevices
# Look for services
zeroconf = Zeroconf() zeroconf = Zeroconf()
browser = ServiceBrowser(zeroconf, "_arduino._tcp.local.", handlers=[on_service_state_change]) browser = ServiceBrowser(zeroconf, "_arduino._tcp.local.", handlers=[on_service_state_change])
discover_last = time.time() discover_last = time.time()
while time.time() < discover_last + DISCOVER_TIMEOUT: while time.time() < discover_last + DISCOVER_TIMEOUT:
None
#zeroconf.close()
pass
# zeroconf.close()
if len(devices) == 0: if len(devices) == 0:
print("Nothing found!\n") print("Nothing found!\n")
@ -287,7 +298,7 @@ if __name__ == '__main__':
# Sort list # Sort list
field = args.sort.lower() field = args.sort.lower()
if field not in devices[0]: if field not in devices[0]:
print("Unknown field '%s'\n" % field)
print("Unknown field '{}'\n".format(field))
sys.exit(1) sys.exit(1)
devices = sorted(devices, key=lambda device: device.get(field, '')) devices = sorted(devices, key=lambda device: device.get(field, ''))
@ -322,23 +333,23 @@ if __name__ == '__main__':
queue = sorted(queue, key=lambda device: device.get('board', '')) queue = sorted(queue, key=lambda device: device.get('board', ''))
# Flash eash board
# Flash each board
for board in queue: for board in queue:
# Flash core version? # Flash core version?
if args.core > 0: if args.core > 0:
board['flags'] = "-DESPURNA_CORE " + board['flags'] board['flags'] = "-DESPURNA_CORE " + board['flags']
env = "esp8266-%dm-ota" % board['size']
env = "esp8266-{:d}m-ota".format(board['size'])
# Summary # Summary
print() print()
print("HOST = %s" % boardname(board))
print("IP = %s" % board['ip'])
print("BOARD = %s" % board['board'])
print("AUTH = %s" % board['auth'])
print("FLAGS = %s" % board['flags'])
print("ENV = %s" % env)
print("HOST = {}".format(boardname(board)))
print("IP = {}".format(board['ip']))
print("BOARD = {}".format(board['board']))
print("AUTH = {}".format(board['auth']))
print("FLAGS = {}".format(board['flags']))
print("ENV = {}".format(env))
response = True response = True
if args.yes == 0: if args.yes == 0:


+ 26
- 1
code/platformio.ini View File

@ -77,7 +77,7 @@ lib_deps =
ArduinoJson ArduinoJson
https://github.com/marvinroger/async-mqtt-client#v0.8.1 https://github.com/marvinroger/async-mqtt-client#v0.8.1
Brzo I2C Brzo I2C
https://github.com/xoseperez/debounceevent.git#2.0.4
https://github.com/xoseperez/debounceevent.git#2.0.5
https://github.com/xoseperez/eeprom_rotate#0.9.2 https://github.com/xoseperez/eeprom_rotate#0.9.2
Embedis Embedis
Encoder Encoder
@ -1207,6 +1207,31 @@ upload_flags = ${common.upload_flags}
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
[env:lyasi-rgb-light]
platform = ${common.platform}
framework = ${common.framework}
board = ${common.board_1m}
board_build.flash_mode = ${common.flash_mode}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m0m} -DLYASI_LIGHT
monitor_speed = ${common.monitor_speed}
extra_scripts = ${common.extra_scripts}
[env:lyasi-rgb-light-ota]
platform = ${common.platform}
framework = ${common.framework}
board = ${common.board_1m}
board_build.flash_mode = ${common.flash_mode}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m0m} -DLYASI_LIGHT
upload_speed = ${common.upload_speed}
upload_port = ${common.upload_port}
upload_flags = ${common.upload_flags}
monitor_speed = ${common.monitor_speed}
extra_scripts = ${common.extra_scripts}
[env:magichome-led-controller] [env:magichome-led-controller]
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}


+ 11
- 7
pre-commit View File

@ -15,17 +15,18 @@ Copy this file to .git/hooks/
""" """
import os import os
import sys
import string
import re import re
import string
import sys
from subprocess import call, check_output from subprocess import call, check_output
try: try:
from urllib.parse import urlparse from urllib.parse import urlparse
except ImportError: except ImportError:
from urlparse import urlparse from urlparse import urlparse
from fileinput import FileInput from fileinput import FileInput
# https://github.com/python/cpython/commit/6cb7b659#diff-78790b53ff259619377058acd4f74672 # https://github.com/python/cpython/commit/6cb7b659#diff-78790b53ff259619377058acd4f74672
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
class FileInputCtx(FileInput): class FileInputCtx(FileInput):
@ -35,6 +36,7 @@ if sys.version_info[0] < 3:
def __exit__(self, type, value, traceback): def __exit__(self, type, value, traceback):
self.close() self.close()
FileInput = FileInputCtx FileInput = FileInputCtx
@ -91,15 +93,15 @@ def espurna_get_version(base, version_h="code/espurna/config/version.h"):
TEMPLATES = { TEMPLATES = {
"![travis]": "[![travis](https://travis-ci.org/{USER}/{REPO}.svg?branch={BRANCH})]" "![travis]": "[![travis](https://travis-ci.org/{USER}/{REPO}.svg?branch={BRANCH})]"
"(https://travis-ci.org/{USER}/{REPO})\n",
"![version]": "[![version](https://img.shields.io/badge/version-{VERSION:escape_hyphen}-brightgreen.svg)](CHANGELOG.md)\n",
"(https://travis-ci.org/{USER}/{REPO})\n",
"![version]": "[![version](https://img.shields.io/badge/version-{VERSION:escape_hyphen}-brightgreen.svg)]"
"(CHANGELOG.md)\n",
"![branch]": "[![branch](https://img.shields.io/badge/branch-{BRANCH:escape_hyphen}-orange.svg)]" "![branch]": "[![branch](https://img.shields.io/badge/branch-{BRANCH:escape_hyphen}-orange.svg)]"
"(https://github.com/{USER}/{REPO}/tree/{BRANCH}/)\n",
"(https://github.com/{USER}/{REPO}/tree/{BRANCH}/)\n",
} }
README = "README.md" README = "README.md"
if __name__ == "__main__": if __name__ == "__main__":
base = os.getcwd() base = os.getcwd()
@ -117,6 +119,7 @@ if __name__ == "__main__":
for k, tmpl in TEMPLATES.items() for k, tmpl in TEMPLATES.items()
] ]
def fmt_line(line): def fmt_line(line):
for match, tmpl in templates: for match, tmpl in templates:
if match in line: if match in line:
@ -124,6 +127,7 @@ if __name__ == "__main__":
return line return line
path = os.path.join(base, README) path = os.path.join(base, README)
with FileInput(path, inplace=True) as readme: with FileInput(path, inplace=True) as readme:


Loading…
Cancel
Save