Browse Source

Merge pull request #1 from xoseperez/dev

merging back from xoseperez
ota
ColinShorts 6 years ago
committed by GitHub
parent
commit
c1c6d145f5
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 280 additions and 12 deletions
  1. +29
    -0
      CHANGELOG.md
  2. +5
    -3
      README.md
  3. +3
    -0
      code/espurna/config/arduino.h
  4. +101
    -0
      code/espurna/config/hardware.h
  5. +2
    -2
      code/espurna/config/version.h
  6. +10
    -1
      code/espurna/ir.ino
  7. +32
    -0
      code/espurna/migrate.ino
  8. +9
    -0
      code/espurna/telnet.ino
  9. +9
    -0
      code/espurna/utils.ino
  10. +80
    -6
      code/platformio.ini

+ 29
- 0
CHANGELOG.md View File

@ -3,6 +3,35 @@
The format is based on [Keep a Changelog](http://keepachangelog.com/) The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [1.12.6] 2018-05-02
### Fixed
- Check NTP_SUPPORT for sensors (thanks to @mcspr)
- Fix AM2302 sensor
- Fix hostname truncated to 20 chars when advertised to DHCP ([#774](https://github.com/xoseperez/espurna/issues/774))
- Decouple Serial object from Terminal, Debug modules ([#787](https://github.com/xoseperez/espurna/issues/787))
- Fix Arilux LC-01 definitions ([#797](https://github.com/xoseperez/espurna/issues/797))
- Do not uppercase hostname in web interface ([#799](https://github.com/xoseperez/espurna/issues/799))
- Ensure scheduler has access to all channels independently of the color mode ([#807](https://github.com/xoseperez/espurna/issues/807))
### Added
- Support for IteadStudio Sonoff S31 ([#497](https://github.com/xoseperez/espurna/issues/497))
- Option to ignore daylight saving in scheduler ([#783](https://github.com/xoseperez/espurna/issues/783))
- Report last energy reset datetime in web interface ([#784](https://github.com/xoseperez/espurna/issues/784))
- Added captive portal in AP mode
- Support for IR toggle mode (thanks to @darshkpatel)
- Support for IteadStudio Sonoff POW R2 (thanks to @ColinShorts)
- Support for Luani HVIO (thanks to @wildwiz)
- Support for Zhilde ZLD-EU55-W power strip (thanks to @wildwiz)
- Support for RFB_DIRECT Sonoff Bridge EFM8BB1 bypass hack (thanks to @wildwiz)
- Support for SenseAir S8 CO2 sensor (thanks to @Yonsm)
- Support for PMS5003T/ST sensors (thanks to @Yonsm)
### Changed
- Updated JustWifi Library
- Some cleanup in the web interface
- Refactored configuration files (thanks to @lobradov, @mcspr)
- Changes pre-commit hook (thanks to @mcspr)
## [1.12.5] 2018-04-08 ## [1.12.5] 2018-04-08
### Fixed ### Fixed
- Fixed expected power calibration ([#676](https://github.com/xoseperez/espurna/issues/676)) - Fixed expected power calibration ([#676](https://github.com/xoseperez/espurna/issues/676))


+ 5
- 3
README.md View File

@ -3,7 +3,7 @@
ESPurna ("spark" in Catalan) is a custom firmware for ESP8285/ESP8266 based smart switches, lights and sensors. ESPurna ("spark" in Catalan) is a custom firmware for ESP8285/ESP8266 based smart switches, lights and sensors.
It uses the Arduino Core for ESP8266 framework and a number of 3rd party libraries. It uses the Arduino Core for ESP8266 framework and a number of 3rd party libraries.
[![version](https://img.shields.io/badge/version-1.12.6a-brightgreen.svg)](CHANGELOG.md)
[![version](https://img.shields.io/badge/version-1.12.6-brightgreen.svg)](CHANGELOG.md)
[![branch](https://img.shields.io/badge/branch-dev-orange.svg)](https://github.org/xoseperez/espurna/tree/dev/) [![branch](https://img.shields.io/badge/branch-dev-orange.svg)](https://github.org/xoseperez/espurna/tree/dev/)
[![travis](https://travis-ci.org/xoseperez/espurna.svg?branch=dev)](https://travis-ci.org/xoseperez/espurna) [![travis](https://travis-ci.org/xoseperez/espurna.svg?branch=dev)](https://travis-ci.org/xoseperez/espurna)
[![codacy](https://img.shields.io/codacy/grade/c9496e25cf07434cba786b462cb15f49/dev.svg)](https://www.codacy.com/app/xoseperez/espurna/dashboard) [![codacy](https://img.shields.io/codacy/grade/c9496e25cf07434cba786b462cb15f49/dev.svg)](https://www.codacy.com/app/xoseperez/espurna/dashboard)
@ -63,6 +63,7 @@ It uses the Arduino Core for ESP8266 framework and a number of 3rd party librari
* Multiple virtual switches (tested with up to 16) * Multiple virtual switches (tested with up to 16)
* MQTT-to-RF two-way bridge (no need to learn codes) * MQTT-to-RF two-way bridge (no need to learn codes)
* Support for [https://github.com/Portisch/RF-Bridge-EFM8BB1](https://github.com/Portisch/RF-Bridge-EFM8BB1) custom firmware * Support for [https://github.com/Portisch/RF-Bridge-EFM8BB1](https://github.com/Portisch/RF-Bridge-EFM8BB1) custom firmware
* Support for [direct control of the encoder/decoder bypassing the EFM8BB1](https://github.com/xoseperez/espurna/wiki/Hardware-Itead-Sonoff-RF-Bridge---Direct-Hack)
* Support for [different **sensors**](Sensors) * Support for [different **sensors**](Sensors)
* Environment * Environment
* **DHT11 / DHT22 / DHT21 / AM2301 / Itead's SI7021** * **DHT11 / DHT22 / DHT21 / AM2301 / Itead's SI7021**
@ -72,7 +73,8 @@ It uses the Arduino Core for ESP8266 framework and a number of 3rd party librari
* **AM2320** temperature and humidity sensor over I2C * **AM2320** temperature and humidity sensor over I2C
* **Dallas OneWire sensors** like the DS18B20 * **Dallas OneWire sensors** like the DS18B20
* **MHZ19** CO2 sensor * **MHZ19** CO2 sensor
* **PMSX003** dust sensor
* **SenseAir S8** CO2 sensor
* **PMSX003/PMS5003T/ST** dust sensors
* **BH1750** luminosity sensor * **BH1750** luminosity sensor
* **GUVAS12SD** UV sensor * **GUVAS12SD** UV sensor
* Power monitoring * Power monitoring
@ -243,7 +245,7 @@ Here is the list of supported hardware. For more information please refer to the
|**Generic DHT11 v1.0**|**Generic DS18B20 v1.0**|| |**Generic DHT11 v1.0**|**Generic DS18B20 v1.0**||
**Other supported boards:** **Other supported boards:**
*TODO*
IteadStudio Sonoff S31, IteadStudio Sonoff POW R2, Zhilde ZLD-EU55-W, Luani HVIO
## License ## License


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

@ -19,6 +19,7 @@
//#define ITEAD_S20 //#define ITEAD_S20
//#define ITEAD_SONOFF_TOUCH //#define ITEAD_SONOFF_TOUCH
//#define ITEAD_SONOFF_POW //#define ITEAD_SONOFF_POW
//#define ITEAD_SONOFF_POW_R2
//#define ITEAD_SONOFF_DUAL //#define ITEAD_SONOFF_DUAL
//#define ITEAD_SONOFF_DUAL_R2 //#define ITEAD_SONOFF_DUAL_R2
//#define ITEAD_SONOFF_4CH //#define ITEAD_SONOFF_4CH
@ -78,6 +79,8 @@
//#define GENERIC_ESP01S_DS18B20_V10 //#define GENERIC_ESP01S_DS18B20_V10
//#define HELTEC_TOUCHRELAY //#define HELTEC_TOUCHRELAY
//#define ZHILDE_EU44_W //#define ZHILDE_EU44_W
//#define LUANI_HVIO
//#define ALLNET_4DUINO_IOT_WLAN_RELAIS
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Features (values below are non-default values) // Features (values below are non-default values)


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

@ -379,6 +379,31 @@
#define HLW8012_CF1_PIN 13 #define HLW8012_CF1_PIN 13
#define HLW8012_CF_PIN 14 #define HLW8012_CF_PIN 14
#elif defined(ITEAD_SONOFF_POW_R2)
// Info
#define MANUFACTURER "ITEAD"
#define DEVICE "SONOFF_POW_R2"
// Buttons
#define BUTTON1_PIN 0
#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
#define BUTTON1_RELAY 1
// Relays
#define RELAY1_PIN 12
#define RELAY1_TYPE RELAY_TYPE_NORMAL
// LEDs
#define LED1_PIN 15
#define LED1_PIN_INVERSE 0
// CSE7766
#ifndef CSE7766_SUPPORT
#define CSE7766_SUPPORT 1
#endif
#define CSE7766_PIN 1
#elif defined(ITEAD_SONOFF_DUAL) #elif defined(ITEAD_SONOFF_DUAL)
// Info // Info
@ -1879,6 +1904,7 @@
// LEDs // LEDs
#define LED1_PIN 2 #define LED1_PIN 2
#define LED1_PIN_INVERSE 0
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -1971,6 +1997,81 @@
#define LED1_PIN 1 #define LED1_PIN 1
#define LED1_PIN_INVERSE 1 #define LED1_PIN_INVERSE 1
// -----------------------------------------------------------------------------
// Allnet 4duino ESP8266-UP-Relais
// http://www.allnet.de/de/allnet-brand/produkte/neuheiten/p/allnet-4duino-iot-wlan-relais-unterputz-esp8266-up-relais/
// https://shop.allnet.de/fileadmin/transfer/products/148814.pdf
// -----------------------------------------------------------------------------
#elif defined(ALLNET_4DUINO_IOT_WLAN_RELAIS)
// Info
#define MANUFACTURER "ALLNET"
#define DEVICE "4DUINO_IOT_WLAN_RELAIS"
// Relays
#define RELAY1_PIN 14
#define RELAY1_RESET_PIN 12
#define RELAY1_TYPE RELAY_TYPE_LATCHED
// LEDs
#define LED1_PIN 0
#define LED1_PIN_INVERSE 1
// Buttons
//#define BUTTON1_PIN 0
//#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
// Using pins labelled as SDA & SCL as buttons
#define BUTTON2_PIN 4
#define BUTTON2_MODE BUTTON_PUSHBUTTON
#define BUTTON2_PRESS BUTTON_MODE_TOGGLE
#define BUTTON2_CLICK BUTTON_MODE_NONE
#define BUTTON2_DBLCLICK BUTTON_MODE_NONE
#define BUTTON2_LNGCLICK BUTTON_MODE_NONE
#define BUTTON2_LNGLNGCLICK BUTTON_MODE_NONE
#define BUTTON3_PIN 5
#define BUTTON3_MODE BUTTON_PUSHBUTTON
// Using pins labelled as SDA & SCL for I2C
//#define I2C_SDA_PIN 4
//#define I2C_SCL_PIN 5
// -----------------------------------------------------------------------------
// Luani HVIO
// https://luani.de/projekte/esp8266-hvio/
// https://luani.de/blog/esp8266-230v-io-modul/
// -----------------------------------------------------------------------------
#elif defined(LUANI_HVIO)
// Info
#define MANUFACTURER "LUANI"
#define DEVICE "HVIO"
// Buttons
#define BUTTON1_PIN 12
#define BUTTON1_RELAY 1
#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
#define BUTTON1_DBLCLICK BUTTON_MODE_NONE
#define BUTTON2_PIN 13
#define BUTTON2_RELAY 2
#define BUTTON2_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
// Relays
#define RELAY1_PIN 4
#define RELAY2_PIN 5
#define RELAY1_TYPE RELAY_TYPE_NORMAL
#define RELAY2_TYPE RELAY_TYPE_NORMAL
// LEDs
#define LED1_PIN 15
#define LED1_PIN_INVERSE 0
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// TEST boards (do not use!!) // TEST boards (do not use!!)
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------


+ 2
- 2
code/espurna/config/version.h View File

@ -1,6 +1,6 @@
#define APP_NAME "ESPURNA" #define APP_NAME "ESPURNA"
#define APP_VERSION "1.12.6a"
#define APP_REVISION ""
#define APP_VERSION "1.12.6"
#define APP_REVISION "db84006"
#define APP_AUTHOR "xose.perez@gmail.com" #define APP_AUTHOR "xose.perez@gmail.com"
#define APP_WEBSITE "http://tinkerman.cat" #define APP_WEBSITE "http://tinkerman.cat"
#define CFG_VERSION 3 #define CFG_VERSION 3

+ 10
- 1
code/espurna/ir.ino View File

@ -14,6 +14,7 @@ Copyright (C) 2017-2018 by François Déchery
IRrecv * _ir_recv; IRrecv * _ir_recv;
decode_results _ir_results; decode_results _ir_results;
unsigned long _ir_last_toggle = 0;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// PRIVATE // PRIVATE
@ -42,9 +43,17 @@ void _irProcessCode(unsigned long code) {
if (button_mode == IR_BUTTON_MODE_STATE) { if (button_mode == IR_BUTTON_MODE_STATE) {
relayStatus(0, button_value); relayStatus(0, button_value);
} }
if (button_mode == IR_BUTTON_MODE_TOGGLE) { if (button_mode == IR_BUTTON_MODE_TOGGLE) {
relayToggle(button_value);
if (millis() - _ir_last_toggle > 250){
relayToggle(button_value);
_ir_last_toggle = millis();
} else {
DEBUG_MSG_P(PSTR("[IR] Ignoring repeated code\n"));
}
} }
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
if (button_mode == IR_BUTTON_MODE_BRIGHTER) { if (button_mode == IR_BUTTON_MODE_BRIGHTER) {


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

@ -905,6 +905,38 @@ void migrate() {
setSetting("relayType", 3, RELAY_TYPE_NORMAL); setSetting("relayType", 3, RELAY_TYPE_NORMAL);
setSetting("relayType", 4, RELAY_TYPE_NORMAL); setSetting("relayType", 4, RELAY_TYPE_NORMAL);
#elif defined(ITEAD_SONOFF_POW_R2)
setSetting("board", 71);
setSetting("ledGPIO", 0, 15);
setSetting("ledLogic", 0, 1);
setSetting("btnGPIO", 0, 0);
setSetting("btnRelay", 0, 0);
setSetting("relayGPIO", 0, 12);
setSetting("relayType", 0, RELAY_TYPE_NORMAL);
setSetting("selGPIO", 5);
setSetting("cf1GPIO", 13);
setSetting("cfGPIO", 14);
#elif defined(LUANI_HVIO)
setSetting("board", 72);
setSetting("ledGPIO", 0, 15);
setSetting("ledLogic", 0, 0);
setSetting("btnGPIO", 0, 12);
setSetting("btnRelay", 0, 0);
setSetting("relayGPIO", 0, 4);
setSetting("relayType", 0, RELAY_TYPE_NORMAL);
setSetting("relayGPIO", 1, 5);
setSetting("relayType", 1, RELAY_TYPE_NORMAL);
#elif defined(ALLNET_4DUINO_IOT_WLAN_RELAIS)
setSetting("board", 73);
setSetting("relayGPIO", 0, 14);
setSetting("relayResetGPIO", 0, 12);
setSetting("relayType", 0, RELAY_TYPE_LATCHED);
#else #else
// Allow users to define new settings without migration config // Allow users to define new settings without migration config


+ 9
- 0
code/espurna/telnet.ino View File

@ -66,6 +66,15 @@ void _telnetData(unsigned char clientId, void *data, size_t len) {
// Capture close connection // Capture close connection
char * p = (char *) data; char * p = (char *) data;
// C-d is sent as two bytes (sometimes repeating)
if (len >= 2) {
if ((p[0] == 0xFF) && (p[1] == 0xEC)) {
_telnetClients[clientId]->close(true);
return;
}
}
if ((strncmp(p, "close", 5) == 0) || (strncmp(p, "quit", 4) == 0)) { if ((strncmp(p, "close", 5) == 0) || (strncmp(p, "quit", 4) == 0)) {
_telnetClients[clientId]->close(); _telnetClients[clientId]->close();
return; return;


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

@ -356,9 +356,15 @@ void info() {
#if ANALOG_SUPPORT #if ANALOG_SUPPORT
DEBUG_MSG_P(PSTR(" ANALOG")); DEBUG_MSG_P(PSTR(" ANALOG"));
#endif #endif
#if BH1750_SUPPORT
DEBUG_MSG_P(PSTR(" BH1750"));
#endif
#if BMX280_SUPPORT #if BMX280_SUPPORT
DEBUG_MSG_P(PSTR(" BMX280")); DEBUG_MSG_P(PSTR(" BMX280"));
#endif #endif
#if CSE7766_SUPPORT
DEBUG_MSG_P(PSTR(" CSE7766"));
#endif
#if DALLAS_SUPPORT #if DALLAS_SUPPORT
DEBUG_MSG_P(PSTR(" DALLAS")); DEBUG_MSG_P(PSTR(" DALLAS"));
#endif #endif
@ -401,6 +407,9 @@ void info() {
#if PZEM004T_SUPPORT #if PZEM004T_SUPPORT
DEBUG_MSG_P(PSTR(" PZEM004T")); DEBUG_MSG_P(PSTR(" PZEM004T"));
#endif #endif
#if SENSEAIR_SUPPORT
DEBUG_MSG_P(PSTR(" SENSEAIR"));
#endif
#if SHT3X_I2C_SUPPORT #if SHT3X_I2C_SUPPORT
DEBUG_MSG_P(PSTR(" SHT3X_I2C")); DEBUG_MSG_P(PSTR(" SHT3X_I2C"));
#endif #endif


+ 80
- 6
code/platformio.ini View File

@ -447,6 +447,31 @@ upload_flags = ${common.upload_flags}
monitor_baud = 115200 monitor_baud = 115200
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-pow-r2]
platform = ${common.platform}
framework = arduino
board = esp01_1m
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_POW_R2
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-pow-r2-ota]
platform = ${common.platform}
framework = arduino
board = esp01_1m
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_POW_R2
upload_speed = 115200
upload_port = ${common.upload_port}
upload_flags = ${common.upload_flags}
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-dual] [env:itead-sonoff-dual]
platform = ${common.platform} platform = ${common.platform}
framework = arduino framework = arduino
@ -738,8 +763,8 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore} lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_RFBRIDGE -DRFB_DIRECT build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_RFBRIDGE -DRFB_DIRECT
upload_speed = 115200 upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
monitor_baud = 19200 monitor_baud = 19200
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
@ -888,8 +913,8 @@ board_flash_mode = dout
lib_deps = ${common.lib_deps} lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore} lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_S31 build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_S31
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
monitor_baud = 115200 monitor_baud = 115200
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
@ -1926,8 +1951,33 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore} lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DZHILDE_EU44_W build_flags = ${common.build_flags_1m} -DZHILDE_EU44_W
upload_speed = 115200 upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:luani-hvio]
platform = ${common.platform}
framework = arduino
board = esp07
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DLUANI_HVIO
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:luani-hvio-ota]
platform = ${common.platform}
framework = arduino
board = esp07
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DZLUANI_HVIO
upload_speed = 115200
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
monitor_baud = 115200 monitor_baud = 115200
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
@ -2054,3 +2104,27 @@ upload_speed = 115200
upload_port = "${env.ESPURNA_IP}" upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266 upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
[env:allnet-4duino-iot-wlan-relais]
platform = ${common.platform}
framework = arduino
board = esp12e
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DALLNET_4DUINO_IOT_WLAN_RELAIS
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:allnet-4duino-iot-wlan-relais-ota]
platform = ${common.platform}
framework = arduino
board = esp12e
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DALLNET_4DUINO_IOT_WLAN_RELAIS
upload_speed = 115200
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
extra_scripts = ${common.extra_scripts}

Loading…
Cancel
Save