mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-28 13:16:32 +00:00
Add command UfsRun
This commit is contained in:
parent
e54487fd24
commit
e16ba61dea
@ -10,7 +10,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
- Support for Frysk language translations by Christiaan Heerze
|
- Support for Frysk language translations by Christiaan Heerze
|
||||||
- ESP8266 Fallback to ``*.bin.gz`` binary when OTA upload of ``*.bin`` binary fails
|
- ESP8266 Fallback to ``*.bin.gz`` binary when OTA upload of ``*.bin`` binary fails
|
||||||
- Berry language improved Tasmota integration
|
- Berry language improved Tasmota integration
|
||||||
- Filesystem commands ``Ufs``, ``UfsType``, ``UfsSize``, ``UfsFree``, ``UfsDelete`` and ``UfsRename``
|
- Filesystem commands ``Ufs``, ``UfsType``, ``UfsSize``, ``UfsFree``, ``UfsDelete``, ``UfsRename`` and ``UfsRun``
|
||||||
- Basic support for filesystem ``autoexec.bat``
|
- Basic support for filesystem ``autoexec.bat``
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@ -95,7 +95,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
|||||||
- Commands ``ZbNameKey``, ``ZbDeviceTopic``, ``ZbNoPrefix``, ``ZbEndpointSuffix``, ``ZbNoAutoBind`` and ``ZbNameTopic`` as synonyms for ``SetOption83, 89, 100, 101, 110`` and ``112``
|
- Commands ``ZbNameKey``, ``ZbDeviceTopic``, ``ZbNoPrefix``, ``ZbEndpointSuffix``, ``ZbNoAutoBind`` and ``ZbNameTopic`` as synonyms for ``SetOption83, 89, 100, 101, 110`` and ``112``
|
||||||
- Commands ``ZbNoAutoBind``, ``ZbReceivedTopic`` and ``ZbOmitDevice`` as synonyms for ``SetOption116, 118`` and ``119``
|
- Commands ``ZbNoAutoBind``, ``ZbReceivedTopic`` and ``ZbOmitDevice`` as synonyms for ``SetOption116, 118`` and ``119``
|
||||||
- Commands ``BuzzerActive`` and ``BuzzerPwm`` as synonyms for ``SetOption67`` and ``111``
|
- Commands ``BuzzerActive`` and ``BuzzerPwm`` as synonyms for ``SetOption67`` and ``111``
|
||||||
- Filesystem commands ``Ufs``, ``UfsType``, ``UfsSize``, ``UfsFree``, ``UfsDelete`` and ``UfsRename``
|
- Filesystem commands ``Ufs``, ``UfsType``, ``UfsSize``, ``UfsFree``, ``UfsDelete``, ``UfsRename`` and ``UfsRun``
|
||||||
- Basic support for filesystem ``autoexec.bat``
|
- Basic support for filesystem ``autoexec.bat``
|
||||||
- Milliseconds to console output [#10152](https://github.com/arendst/Tasmota/issues/10152)
|
- Milliseconds to console output [#10152](https://github.com/arendst/Tasmota/issues/10152)
|
||||||
- Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196)
|
- Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196)
|
||||||
|
@ -370,10 +370,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE
|
|||||||
|
|
||||||
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
||||||
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
|
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
|
||||||
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_AUTOEXEC, SRC_MAX };
|
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_MAX };
|
||||||
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
|
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
|
||||||
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
|
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
|
||||||
"Thermostat|Chat|TCL|Berry|Autoexec";
|
"Thermostat|Chat|TCL|Berry|File";
|
||||||
|
|
||||||
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
|
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
|
||||||
|
|
||||||
|
@ -426,6 +426,9 @@ void Scheduler(void) {
|
|||||||
DeviceGroupsLoop();
|
DeviceGroupsLoop();
|
||||||
#endif // USE_DEVICE_GROUPS
|
#endif // USE_DEVICE_GROUPS
|
||||||
BacklogLoop();
|
BacklogLoop();
|
||||||
|
#ifdef USE_UFILESYS
|
||||||
|
FileRunLoop();
|
||||||
|
#endif // USE_UFILESYS
|
||||||
|
|
||||||
static uint32_t state_50msecond = 0; // State 50msecond timer
|
static uint32_t state_50msecond = 0; // State 50msecond timer
|
||||||
if (TimeReached(state_50msecond)) {
|
if (TimeReached(state_50msecond)) {
|
||||||
|
@ -85,8 +85,10 @@ uint8_t ufs_type;
|
|||||||
uint8_t ffs_type;
|
uint8_t ffs_type;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
char run_file[48];
|
||||||
|
int run_file_pos = -1;
|
||||||
|
bool run_file_mutex = 0;
|
||||||
bool download_busy;
|
bool download_busy;
|
||||||
bool autoexec = false;
|
|
||||||
} UfsData;
|
} UfsData;
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
@ -127,8 +129,9 @@ void UfsInitOnce(void) {
|
|||||||
dfsp = ffsp;
|
dfsp = ffsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// actually this inits flash file only
|
// Called from tasmota.ino at restart. This inits flash file only
|
||||||
void UfsInit(void) {
|
void UfsInit(void) {
|
||||||
|
UfsData.run_file_pos = -1;
|
||||||
UfsInitOnce();
|
UfsInitOnce();
|
||||||
if (ufs_type) {
|
if (ufs_type) {
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("UFS: FlashFS mounted with %d kB free"), UfsInfo(1, 0));
|
AddLog(LOG_LEVEL_INFO, PSTR("UFS: FlashFS mounted with %d kB free"), UfsInfo(1, 0));
|
||||||
@ -350,37 +353,59 @@ bool TfsRenameFile(const char *fname1, const char *fname2) {
|
|||||||
* Autoexec support
|
* Autoexec support
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
void UfsAutoexec(void) {
|
|
||||||
if (!ffs_type) { return; }
|
|
||||||
File file = ffsp->open(TASM_FILE_AUTOEXEC, "r");
|
|
||||||
if (!file) { return; }
|
|
||||||
|
|
||||||
char cmd_line[512];
|
void FileRunLoop(void) {
|
||||||
while (file.available()) {
|
if (UfsData.run_file_pos < 0) { return; }
|
||||||
uint16_t index = 0;
|
if (!ffs_type) { return; }
|
||||||
|
|
||||||
|
if (strlen(UfsData.run_file) && !UfsData.run_file_mutex) {
|
||||||
|
File file = ffsp->open(UfsData.run_file, "r");
|
||||||
|
if (!file) { return; }
|
||||||
|
if (!file.seek(UfsData.run_file_pos)) { return; }
|
||||||
|
|
||||||
|
UfsData.run_file_mutex = true;
|
||||||
|
|
||||||
|
char cmd_line[512];
|
||||||
|
cmd_line[0] = '\0'; // Clear in case of re-entry
|
||||||
while (file.available()) {
|
while (file.available()) {
|
||||||
uint8_t buf[1];
|
uint16_t index = 0;
|
||||||
file.read(buf, 1);
|
while (file.available()) {
|
||||||
if ((buf[0] == '\n') || (buf[0] == '\r')) {
|
uint8_t buf[1];
|
||||||
// Line terminated with linefeed or carriage return
|
file.read(buf, 1);
|
||||||
|
if ((buf[0] == '\n') || (buf[0] == '\r')) {
|
||||||
|
break; // Line terminated with linefeed or carriage return
|
||||||
|
}
|
||||||
|
else if (index && (buf[0] == ';')) {
|
||||||
|
break; // End of multi command line
|
||||||
|
}
|
||||||
|
else if ((0 == index) && isspace(buf[0])) {
|
||||||
|
// Skip leading spaces (' ','\t','\n','\v','\f','\r')
|
||||||
|
}
|
||||||
|
else if (index < sizeof(cmd_line) - 2) {
|
||||||
|
cmd_line[index++] = buf[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((index > 0) && (index < sizeof(cmd_line) - 1) && (cmd_line[0] != ';')) {
|
||||||
|
// No comment so try to execute command
|
||||||
|
cmd_line[index] = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ((0 == index) && isspace(buf[0])) {
|
|
||||||
// Skip leading spaces (' ','\t','\n','\v','\f','\r')
|
|
||||||
}
|
|
||||||
else if (index < sizeof(cmd_line) - 2) {
|
|
||||||
cmd_line[index++] = buf[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((index > 0) && (index < sizeof(cmd_line) - 1) && (cmd_line[0] != ';')) {
|
UfsData.run_file_pos = (file.available()) ? file.position() : -1;
|
||||||
// No comment so try to execute command
|
file.close();
|
||||||
cmd_line[index] = 0;
|
if (strlen(cmd_line)) {
|
||||||
ExecuteCommand(cmd_line, SRC_AUTOEXEC);
|
ExecuteCommand(cmd_line, SRC_FILE);
|
||||||
}
|
}
|
||||||
delay(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
UfsData.run_file_mutex = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UfsAutoexec(void) {
|
||||||
|
if (TfsFileExists(TASM_FILE_AUTOEXEC)) {
|
||||||
|
snprintf(UfsData.run_file, sizeof(UfsData.run_file), TASM_FILE_AUTOEXEC);
|
||||||
|
UfsData.run_file_pos = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
@ -388,10 +413,10 @@ void UfsAutoexec(void) {
|
|||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
const char kUFSCommands[] PROGMEM = "Ufs|" // Prefix
|
const char kUFSCommands[] PROGMEM = "Ufs|" // Prefix
|
||||||
"|Type|Size|Free|Delete|Rename";
|
"|Type|Size|Free|Delete|Rename|Run";
|
||||||
|
|
||||||
void (* const kUFSCommand[])(void) PROGMEM = {
|
void (* const kUFSCommand[])(void) PROGMEM = {
|
||||||
&UFSInfo, &UFSType, &UFSSize, &UFSFree, &UFSDelete, &UFSRename};
|
&UFSInfo, &UFSType, &UFSSize, &UFSFree, &UFSDelete, &UFSRename, &UFSRun};
|
||||||
|
|
||||||
void UFSInfo(void) {
|
void UFSInfo(void) {
|
||||||
Response_P(PSTR("{\"Ufs\":{\"Type\":%d,\"Size\":%d,\"Free\":%d}"), ufs_type, UfsInfo(0, 0), UfsInfo(1, 0));
|
Response_P(PSTR("{\"Ufs\":{\"Type\":%d,\"Size\":%d,\"Free\":%d}"), ufs_type, UfsInfo(0, 0), UfsInfo(1, 0));
|
||||||
@ -465,6 +490,18 @@ void UFSRename(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UFSRun(void) {
|
||||||
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
if ((UfsData.run_file_pos < 0) && TfsFileExists(XdrvMailbox.data)) {
|
||||||
|
snprintf(UfsData.run_file, sizeof(UfsData.run_file), XdrvMailbox.data);
|
||||||
|
UfsData.run_file_pos = 0;
|
||||||
|
ResponseClear();
|
||||||
|
} else {
|
||||||
|
ResponseCmndChar(PSTR(D_JSON_FAILED));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Web support
|
* Web support
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
@ -824,16 +861,8 @@ bool Xdrv50(uint8_t function) {
|
|||||||
UfsCheckSDCardInit();
|
UfsCheckSDCardInit();
|
||||||
break;
|
break;
|
||||||
#endif // USE_SDCARD
|
#endif // USE_SDCARD
|
||||||
case FUNC_EVERY_SECOND:
|
|
||||||
if (UfsData.autoexec) {
|
|
||||||
// Safe to execute autoexec commands here
|
|
||||||
UfsData.autoexec = false;
|
|
||||||
if (!TasmotaGlobal.no_autoexec) { UfsAutoexec(); }
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FUNC_MQTT_INIT:
|
case FUNC_MQTT_INIT:
|
||||||
// Do not execute autoexec commands here
|
if (!TasmotaGlobal.no_autoexec) { UfsAutoexec(); }
|
||||||
UfsData.autoexec = true;
|
|
||||||
break;
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
result = DecodeCommand(kUFSCommands, kUFSCommand);
|
result = DecodeCommand(kUFSCommands, kUFSCommand);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user