mirror of https://github.com/arendst/Tasmota.git
commit
5770e8f983
|
@ -0,0 +1,334 @@
|
|||
/**************************************************************************//**
|
||||
* \brief EEPROM 24C128 / 24C256 library for Arduino
|
||||
* \author Copyright (C) 2012 Julien Le Sech - www.idreammicro.com
|
||||
* \version 1.0
|
||||
* \date 20120203
|
||||
*
|
||||
* This file is part of the EEPROM 24C128 / 24C256 library for Arduino.
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This library 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 Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see http://www.gnu.org/licenses/
|
||||
******************************************************************************/
|
||||
|
||||
/**************************************************************************//**
|
||||
* \file Eeprom24C128_256.cpp
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* Header file inclusions.
|
||||
******************************************************************************/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#include <Eeprom24C128_256.h>
|
||||
|
||||
/******************************************************************************
|
||||
* Private macro definitions.
|
||||
******************************************************************************/
|
||||
|
||||
/**************************************************************************//**
|
||||
* \def EEPROM__PAGE_SIZE
|
||||
* \brief Size of a page in EEPROM memory.
|
||||
* This size is given by EEPROM memory datasheet.
|
||||
******************************************************************************/
|
||||
#define EEPROM__PAGE_SIZE 64
|
||||
|
||||
/**************************************************************************//**
|
||||
* \def EEPROM__RD_BUFFER_SIZE
|
||||
* \brief Size of input TWI buffer.
|
||||
* This size is equal to BUFFER_LENGTH defined in Wire library (32 bytes).
|
||||
******************************************************************************/
|
||||
#define xBUFFER_LENGTH 24
|
||||
#define EEPROM__RD_BUFFER_SIZE xBUFFER_LENGTH
|
||||
|
||||
/**************************************************************************//**
|
||||
* \def EEPROM__WR_BUFFER_SIZE
|
||||
* \brief Size of output TWI buffer.
|
||||
* This size is equal to BUFFER_LENGTH - 2 bytes reserved for address.
|
||||
******************************************************************************/
|
||||
#define EEPROM__WR_BUFFER_SIZE (xBUFFER_LENGTH - 2)
|
||||
|
||||
/******************************************************************************
|
||||
* Public method definitions.
|
||||
******************************************************************************/
|
||||
|
||||
/**************************************************************************//**
|
||||
* \fn Eeprom24C128_256::Eeprom24C128_256(byte deviceAddress)
|
||||
*
|
||||
* \brief Constructor.
|
||||
*
|
||||
* \param deviceAddress EEPROM address on TWI bus.
|
||||
******************************************************************************/
|
||||
Eeprom24C128_256::Eeprom24C128_256
|
||||
(
|
||||
byte deviceAddress
|
||||
){
|
||||
m_deviceAddress = deviceAddress;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* \fn void Eeprom24C128_256::initialize()
|
||||
*
|
||||
* \brief Initialize library and TWI bus.
|
||||
*
|
||||
* If several devices are connected to TWI bus, this method mustn't be
|
||||
* called. TWI bus must be initialized out of this library using
|
||||
* Wire.begin() method.
|
||||
******************************************************************************/
|
||||
void
|
||||
Eeprom24C128_256::initialize()
|
||||
{
|
||||
Wire.begin();
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* \fn void Eeprom24C128_256::writeByte(
|
||||
* word address,
|
||||
* byte data)
|
||||
*
|
||||
* \brief Write a byte in EEPROM memory.
|
||||
*
|
||||
* \remarks A delay of 10 ms is required after write cycle.
|
||||
*
|
||||
* \param address Address.
|
||||
* \param data Byte to write.
|
||||
******************************************************************************/
|
||||
void
|
||||
Eeprom24C128_256::writeByte
|
||||
(
|
||||
word address,
|
||||
byte data
|
||||
){
|
||||
Wire.beginTransmission(m_deviceAddress);
|
||||
Wire.write(address >> 8);
|
||||
Wire.write(address & 0xFF);
|
||||
Wire.write(data);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* \fn void Eeprom24C128_256::writeBytes(
|
||||
* word address,
|
||||
* word length,
|
||||
* byte* p_data)
|
||||
*
|
||||
* \brief Write bytes in EEPROM memory.
|
||||
*
|
||||
* \param address Start address.
|
||||
* \param length Number of bytes to write.
|
||||
* \param[in] p_data Bytes to write.
|
||||
******************************************************************************/
|
||||
void
|
||||
Eeprom24C128_256::writeBytes
|
||||
(
|
||||
word address,
|
||||
word length,
|
||||
byte* p_data
|
||||
){
|
||||
// Write first page if not aligned.
|
||||
byte notAlignedLength = 0;
|
||||
byte pageOffset = address % EEPROM__PAGE_SIZE;
|
||||
if (pageOffset > 0)
|
||||
{
|
||||
notAlignedLength = EEPROM__PAGE_SIZE - pageOffset;
|
||||
if (length < notAlignedLength)
|
||||
{
|
||||
notAlignedLength = length;
|
||||
}
|
||||
writePage(address, notAlignedLength, p_data);
|
||||
length -= notAlignedLength;
|
||||
}
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
address += notAlignedLength;
|
||||
p_data += notAlignedLength;
|
||||
|
||||
// Write complete and aligned pages.
|
||||
word pageCount = length / EEPROM__PAGE_SIZE;
|
||||
for (word i = 0; i < pageCount; i++)
|
||||
{
|
||||
writePage(address, EEPROM__PAGE_SIZE, p_data);
|
||||
address += EEPROM__PAGE_SIZE;
|
||||
p_data += EEPROM__PAGE_SIZE;
|
||||
length -= EEPROM__PAGE_SIZE;
|
||||
}
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
// Write remaining uncomplete page.
|
||||
writePage(address, length, p_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* \fn byte Eeprom24C128_256::readByte(word address)
|
||||
*
|
||||
* \brief Read a byte in EEPROM memory.
|
||||
*
|
||||
* \param address Address.
|
||||
*
|
||||
* \return Read byte.
|
||||
******************************************************************************/
|
||||
byte
|
||||
Eeprom24C128_256::readByte
|
||||
(
|
||||
word address
|
||||
){
|
||||
Wire.beginTransmission(m_deviceAddress);
|
||||
Wire.write(address >> 8);
|
||||
Wire.write(address & 0xFF);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(m_deviceAddress, (byte)1);
|
||||
byte data = 0;
|
||||
if (Wire.available())
|
||||
{
|
||||
data = Wire.read();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* \fn void Eeprom24C128_256::readBytes(
|
||||
* word address,
|
||||
* word length,
|
||||
* byte* p_data)
|
||||
*
|
||||
* \brief Read bytes in EEPROM memory.
|
||||
*
|
||||
* \param address Start address.
|
||||
* \param length Number of bytes to read.
|
||||
* \patam[in] p_data Byte array to fill with read bytes.
|
||||
******************************************************************************/
|
||||
void
|
||||
Eeprom24C128_256::readBytes
|
||||
(
|
||||
word address,
|
||||
word length,
|
||||
byte* p_data
|
||||
){
|
||||
byte bufferCount = length / EEPROM__RD_BUFFER_SIZE;
|
||||
for (byte i = 0; i < bufferCount; i++)
|
||||
{
|
||||
word offset = i * EEPROM__RD_BUFFER_SIZE;
|
||||
readBuffer(address + offset, EEPROM__RD_BUFFER_SIZE, p_data + offset);
|
||||
}
|
||||
|
||||
byte remainingBytes = length % EEPROM__RD_BUFFER_SIZE;
|
||||
word offset = length - remainingBytes;
|
||||
readBuffer(address + offset, remainingBytes, p_data + offset);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private method definitions.
|
||||
******************************************************************************/
|
||||
|
||||
/**************************************************************************//**
|
||||
* \fn void Eeprom24C128_256::writePage(
|
||||
* word address,
|
||||
* byte length,
|
||||
* byte* p_data)
|
||||
*
|
||||
* \brief Write page in EEPROM memory.
|
||||
*
|
||||
* \param address Start address.
|
||||
* \param length Number of bytes (EEPROM__PAGE_SIZE bytes max).
|
||||
* \param[in] p_data Data.
|
||||
******************************************************************************/
|
||||
void
|
||||
Eeprom24C128_256::writePage
|
||||
(
|
||||
word address,
|
||||
byte length,
|
||||
byte* p_data
|
||||
){
|
||||
// Write complete buffers.
|
||||
byte bufferCount = length / EEPROM__WR_BUFFER_SIZE;
|
||||
for (byte i = 0; i < bufferCount; i++)
|
||||
{
|
||||
byte offset = i * EEPROM__WR_BUFFER_SIZE;
|
||||
writeBuffer(address + offset, EEPROM__WR_BUFFER_SIZE, p_data + offset);
|
||||
}
|
||||
|
||||
// Write remaining bytes.
|
||||
byte remainingBytes = length % EEPROM__WR_BUFFER_SIZE;
|
||||
byte offset = length - remainingBytes;
|
||||
writeBuffer(address + offset, remainingBytes, p_data + offset);
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* \fn void Eeprom24C128_256::writeBuffer(
|
||||
* word address,
|
||||
* byte length,
|
||||
* byte* p_data)
|
||||
*
|
||||
* \brief Write bytes into memory.
|
||||
*
|
||||
* \param address Start address.
|
||||
* \param length Number of bytes (EEPROM__WR_BUFFER_SIZE bytes max).
|
||||
* \param[in] p_data Data.
|
||||
******************************************************************************/
|
||||
void
|
||||
Eeprom24C128_256::writeBuffer
|
||||
(
|
||||
word address,
|
||||
byte length,
|
||||
byte* p_data
|
||||
){
|
||||
Wire.beginTransmission(m_deviceAddress);
|
||||
Wire.write(address >> 8);
|
||||
Wire.write(address & 0xFF);
|
||||
for (byte i = 0; i < length; i++)
|
||||
{
|
||||
Wire.write(p_data[i]);
|
||||
}
|
||||
Wire.endTransmission();
|
||||
|
||||
// Write cycle time (tWR). See EEPROM memory datasheet for more details.
|
||||
delay(10);
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* \fn void Eeprom24C128_256::readBuffer(
|
||||
* word address,
|
||||
* byte length,
|
||||
* byte* p_data)
|
||||
*
|
||||
* \brief Read bytes in memory.
|
||||
*
|
||||
* \param address Start address.
|
||||
* \param length Number of bytes (EEPROM__RD_BUFFER_SIZE bytes max).
|
||||
* \param[in] p_data Buffer to fill with read bytes.
|
||||
******************************************************************************/
|
||||
void
|
||||
Eeprom24C128_256::readBuffer
|
||||
(
|
||||
word address,
|
||||
byte length,
|
||||
byte* p_data
|
||||
){
|
||||
Wire.beginTransmission(m_deviceAddress);
|
||||
Wire.write(address >> 8);
|
||||
Wire.write(address & 0xFF);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(m_deviceAddress, length);
|
||||
for (byte i = 0; i < length; i++)
|
||||
{
|
||||
if (Wire.available())
|
||||
{
|
||||
p_data[i] = Wire.read();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
/**************************************************************************//**
|
||||
* \brief EEPROM 24C128 / 24C256 library for Arduino
|
||||
* \author Copyright (C) 2012 Julien Le Sech - www.idreammicro.com
|
||||
* \version 1.0
|
||||
* \date 20120203
|
||||
*
|
||||
* This file is part of the EEPROM 24C128 / 24C256 library for Arduino.
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This library 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 Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see http://www.gnu.org/licenses/
|
||||
******************************************************************************/
|
||||
|
||||
/**************************************************************************//**
|
||||
* \headerfile Eeprom24C128_256.h
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef Eeprom24C128_256_h
|
||||
#define Eeprom24C128_256_h
|
||||
|
||||
/******************************************************************************
|
||||
* Header file inclusion.
|
||||
******************************************************************************/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
/**************************************************************************//**
|
||||
* \class Eeprom24C128_256
|
||||
*
|
||||
* \brief EEPROM 24C128 / 24C256 memory driver.
|
||||
*
|
||||
* This driver is mainly designed for 24C128 and 24C256 EEPROM memories. It's
|
||||
* also suitable for 24C512 memories.
|
||||
******************************************************************************/
|
||||
class Eeprom24C128_256
|
||||
{
|
||||
public:
|
||||
|
||||
/******************************************************************//**
|
||||
* \fn Eeprom24C128_256(byte deviceAddress)
|
||||
*
|
||||
* \brief Constructor.
|
||||
*
|
||||
* \param deviceAddress EEPROM address on TWI bus.
|
||||
**********************************************************************/
|
||||
Eeprom24C128_256
|
||||
(
|
||||
byte deviceAddress
|
||||
);
|
||||
|
||||
/******************************************************************//**
|
||||
* \fn void initialize()
|
||||
*
|
||||
* \brief Initialize library abnd TWI bus.
|
||||
*
|
||||
* If several devices are connected to TWI bus, this method mustn't be
|
||||
* called. TWI bus must be initialized out of this library using
|
||||
* Wire.begin() method.
|
||||
**********************************************************************/
|
||||
void
|
||||
initialize();
|
||||
|
||||
/******************************************************************//**
|
||||
* \fn void writeByte(
|
||||
* word address,
|
||||
* byte data)
|
||||
*
|
||||
* \brief Write a byte in EEPROM memory.
|
||||
*
|
||||
* \remarks A delay of 10 ms is required after write cycle.
|
||||
*
|
||||
* \param address Address.
|
||||
* \param data Byte to write.
|
||||
**********************************************************************/
|
||||
void
|
||||
writeByte
|
||||
(
|
||||
word address,
|
||||
byte data
|
||||
);
|
||||
|
||||
/******************************************************************//**
|
||||
* \fn void writeBytes(
|
||||
* word address,
|
||||
* word length,
|
||||
* byte* p_data)
|
||||
*
|
||||
* \brief Write bytes in EEPROM memory.
|
||||
*
|
||||
* \param address Start address.
|
||||
* \param length Number of bytes to write.
|
||||
* \param[in] p_data Bytes to write.
|
||||
**********************************************************************/
|
||||
void
|
||||
writeBytes
|
||||
(
|
||||
word address,
|
||||
word length,
|
||||
byte* p_data
|
||||
);
|
||||
|
||||
/******************************************************************//**
|
||||
* \fn byte readByte(word address)
|
||||
*
|
||||
* \brief Read a byte in EEPROM memory.
|
||||
*
|
||||
* \param address Address.
|
||||
*
|
||||
* \return Read byte.
|
||||
**********************************************************************/
|
||||
byte
|
||||
readByte
|
||||
(
|
||||
word address
|
||||
);
|
||||
|
||||
/******************************************************************//**
|
||||
* \fn void readBytes(
|
||||
* word address,
|
||||
* word length,
|
||||
* byte* p_data)
|
||||
*
|
||||
* \brief Read bytes in EEPROM memory.
|
||||
*
|
||||
* \param address Start address.
|
||||
* \param length Number of bytes to read.
|
||||
* \patam[in] p_data Byte array to fill with read bytes.
|
||||
**********************************************************************/
|
||||
void
|
||||
readBytes
|
||||
(
|
||||
word address,
|
||||
word length,
|
||||
byte* p_buffer
|
||||
);
|
||||
|
||||
private:
|
||||
|
||||
byte m_deviceAddress;
|
||||
|
||||
/******************************************************************//**
|
||||
* \fn void writePage(
|
||||
* word address,
|
||||
* byte length,
|
||||
* byte* p_data)
|
||||
*
|
||||
* \brief Write page in EEPROM memory.
|
||||
*
|
||||
* \param address Start address.
|
||||
* \param length Number of bytes (64 bytes max).
|
||||
* \param[in] p_data Data.
|
||||
**********************************************************************/
|
||||
void
|
||||
writePage
|
||||
(
|
||||
word address,
|
||||
byte length,
|
||||
byte* p_data
|
||||
);
|
||||
|
||||
/******************************************************************//**
|
||||
* \fn void writeBuffer(
|
||||
* word address,
|
||||
* byte length,
|
||||
* byte* p_data)
|
||||
*
|
||||
* \brief Write bytes into memory.
|
||||
*
|
||||
* \param address Start address.
|
||||
* \param length Number of bytes (30 bytes max).
|
||||
* \param[in] p_date Data.
|
||||
**********************************************************************/
|
||||
void
|
||||
writeBuffer
|
||||
(
|
||||
word address,
|
||||
byte length,
|
||||
byte* p_data
|
||||
);
|
||||
|
||||
/******************************************************************//**
|
||||
* \fn void readBuffer(
|
||||
* word address,
|
||||
* byte length,
|
||||
* byte* p_data)
|
||||
*
|
||||
* \brief Read bytes in memory.
|
||||
*
|
||||
* \param address Start address.
|
||||
* \param length Number of bytes to read (32 bytes max).
|
||||
* \param[in] p_data Buffer to fill with read bytes.
|
||||
**********************************************************************/
|
||||
void
|
||||
readBuffer
|
||||
(
|
||||
word address,
|
||||
byte length,
|
||||
byte* p_data
|
||||
);
|
||||
};
|
||||
|
||||
#endif // Eeprom24C128_256_h
|
||||
|
18
scripter.md
18
scripter.md
|
@ -52,6 +52,7 @@ executed on BOOT time
|
|||
|
||||
>**\>T**
|
||||
executed on teleperiod time (**SENSOR** and **STATE**), get tele vars only in this section
|
||||
remark: json variable names (like all others) may not contain math operators like - , you should set setoption64 1 to replace - with underscore
|
||||
|
||||
>**\>F**
|
||||
executed every 100 ms
|
||||
|
@ -177,7 +178,7 @@ the condition may not be enclosed in brackets
|
|||
**svars** save permanent vars
|
||||
**delay(x)** pauses x milliseconds (should be as short as possible)
|
||||
**spin(x m)** set gpio pin x (0-16) to value m (0,1) only the last bit is used, so even values set the pin to zero and uneven values set the pin to 1
|
||||
**spinm(x m)** set pin mode gpio pin x (0-16) to mode m (input=0,output=1)
|
||||
**spinm(x m)** set pin mode gpio pin x (0-16) to mode m (input=0,output=1,input with pullup=2)
|
||||
|
||||
>**#name** names a subroutine, subroutines are called with **=#name**
|
||||
**#name(param)** names a subroutines with a parameter is called with **=#name(param)**
|
||||
|
@ -195,7 +196,6 @@ specifies a for next loop, (loop count must not be less then 1)
|
|||
specifies a switch case selector (numeric or string)
|
||||
|
||||
**sd card support**
|
||||
(currently only works with 2.42 ???)
|
||||
enable by CARD_CS = gpio pin of card chip select (+ 10k flash)
|
||||
\#define USE_SCRIPT_FATFS CARD_CS
|
||||
sd card uses standard hardware spi gpios: mosi,miso,sclk
|
||||
|
@ -236,6 +236,18 @@ can be used e.g. to set variables e.g. **script >mintmp=15**
|
|||
more then one line may be executed seperated by a semicolon e.g. **script >mintmp=15;maxtemp=40**
|
||||
script itself cant be set because the size would not fit the mqtt buffers
|
||||
|
||||
**subscribe,unsubscribe**
|
||||
>if \#defined SUPPORT_MQTT_EVENT command subscribe and unsubscribe are supported. in contrast to rules no event is generated but the event name specifies a variable defined in D section and this variable is automatically set on transmission of the subscribed item
|
||||
|
||||
**summary of optional defines**
|
||||
>\#define USE_SCRIPT_FATFS CS_PIN : enables SD card support (on spi bus) also enables 4k script buffer
|
||||
\#define USE_SCRIPT_FATFS_EXT : enables additional FS commands
|
||||
\#define SDCARD_DIR : enables support for WEBUI for SD card directory up and download
|
||||
\#define USE_24C256 : enables use of 24C256 i2c eeprom to expand script buffer (defaults to 4k)
|
||||
\#define SUPPORT_MQTT_EVENT : enables support for subscribe unsubscribe
|
||||
\#define USE_TOUCH_BUTTONS : enable virtual touch button support with touch displays
|
||||
|
||||
|
||||
***example script***
|
||||
meant to show some of the possibilities
|
||||
(actually this code ist too large)
|
||||
|
@ -531,7 +543,7 @@ str=""
|
|||
**\>B**
|
||||
; set sensor file download link
|
||||
fl1("slog.txt")
|
||||
; delete file in case we want to start fresh
|
||||
; delete file in case we want to start fresh
|
||||
;fd("slog.txt")
|
||||
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ no math hierarchy (costs ram and execution time, better group with brackets, an
|
|||
(will probably make math hierarchy an ifdefed option)
|
||||
keywords if then else endif, or, and are better readable for beginners (others may use {})
|
||||
|
||||
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XDRV_10 10
|
||||
|
@ -68,6 +69,16 @@ enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD};
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_MQTT_EVENT
|
||||
#include <LinkedList.h> // Import LinkedList library
|
||||
typedef struct {
|
||||
String Event;
|
||||
String Topic;
|
||||
String Key;
|
||||
} MQTT_Subscription;
|
||||
LinkedList<MQTT_Subscription> subscriptions;
|
||||
#endif //SUPPORT_MQTT_EVENT
|
||||
|
||||
#ifdef USE_TOUCH_BUTTONS
|
||||
#include <renderer.h>
|
||||
extern Adafruit_GFX_Button *buttons[MAXBUTTONS];
|
||||
|
@ -194,6 +205,7 @@ void RulesTeleperiod(void) {
|
|||
|
||||
// EEPROM MACROS
|
||||
#ifdef USE_24C256
|
||||
#ifndef USE_SCRIPT_FATFS
|
||||
// i2c eeprom
|
||||
#include <Eeprom24C128_256.h>
|
||||
#define EEPROM_ADDRESS 0x50
|
||||
|
@ -205,6 +217,7 @@ static Eeprom24C128_256 eeprom(EEPROM_ADDRESS);
|
|||
// eeprom.readBytes(address, length, buffer);
|
||||
#define EEP_READ(A,B,C) eeprom.readBytes(A,B,(uint8_t*)C);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SCRIPT_SKIP_SPACES while (*lp==' ' || *lp=='\t') lp++;
|
||||
#define SCRIPT_SKIP_EOL while (*lp==SCRIPT_EOL) lp++;
|
||||
|
@ -2138,11 +2151,11 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||
SCRIPT_SKIP_SPACES
|
||||
lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
|
||||
int8_t mode=fvar;
|
||||
pinMode(pinnr,mode&1);
|
||||
pinMode(pinnr,mode&3);
|
||||
goto next_line;
|
||||
} else if (!strncmp(lp,"spin(",5)) {
|
||||
lp+=5;
|
||||
// set pin mode
|
||||
// set pin
|
||||
lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
|
||||
int8_t pinnr=fvar;
|
||||
SCRIPT_SKIP_SPACES
|
||||
|
@ -2946,10 +2959,12 @@ void ScriptSaveSettings(void) {
|
|||
strlcpy(glob_script_mem.script_ram,str.c_str(), glob_script_mem.script_size);
|
||||
|
||||
#ifdef USE_24C256
|
||||
#ifndef USE_SCRIPT_FATFS
|
||||
if (glob_script_mem.flags&1) {
|
||||
EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_SCRIPT_FATFS
|
||||
if (glob_script_mem.flags&1) {
|
||||
|
@ -2991,9 +3006,12 @@ char *svd_sp=glob_script_mem.scriptptr;
|
|||
glob_script_mem.scriptptr=svd_sp;
|
||||
Scripter_save_pvars();
|
||||
}
|
||||
#define D_CMND_SCRIPT "Script"
|
||||
#define D_CMND_SUBSCRIBE "Subscribe"
|
||||
#define D_CMND_UNSUBSCRIBE "Unsubscribe"
|
||||
|
||||
enum ScriptCommands { CMND_SCRIPT };
|
||||
const char kScriptCommands[] PROGMEM = "Script";
|
||||
enum ScriptCommands { CMND_SCRIPT,CMND_SUBSCRIBE, CMND_UNSUBSCRIBE };
|
||||
const char kScriptCommands[] PROGMEM = D_CMND_SCRIPT "|" D_CMND_SUBSCRIBE "|" D_CMND_UNSUBSCRIBE;
|
||||
|
||||
bool ScriptCommand(void) {
|
||||
char command[CMDSZ];
|
||||
|
@ -3026,8 +3044,15 @@ bool ScriptCommand(void) {
|
|||
return serviced;
|
||||
}
|
||||
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\",\"Free\":%d}"),command, GetStateText(bitRead(Settings.rule_enabled,0)),glob_script_mem.script_size-strlen(glob_script_mem.script_ram));
|
||||
} else serviced = false;
|
||||
|
||||
#ifdef SUPPORT_MQTT_EVENT
|
||||
} else if (CMND_SUBSCRIBE == command_code) { //MQTT Subscribe command. Subscribe <Event>, <Topic> [, <Key>]
|
||||
String result = ScriptSubscribe(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||
Response_P(S_JSON_COMMAND_SVALUE, command, result.c_str());
|
||||
} else if (CMND_UNSUBSCRIBE == command_code) { //MQTT Un-subscribe command. UnSubscribe <Event>
|
||||
String result = ScriptUnsubscribe(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||
Response_P(S_JSON_COMMAND_SVALUE, command, result.c_str());
|
||||
#endif //SUPPORT_MQTT_EVENT
|
||||
}
|
||||
return serviced;
|
||||
}
|
||||
|
||||
|
@ -3050,6 +3075,196 @@ void dateTime(uint16_t* date, uint16_t* time) {
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef SUPPORT_MQTT_EVENT
|
||||
/********************************************************************************************/
|
||||
/*
|
||||
* Script: Process received MQTT message.
|
||||
* If the message is in our subscription list, trigger an event with the value parsed from MQTT data
|
||||
* Input:
|
||||
* void - We are going to access XdrvMailbox data directly.
|
||||
* Return:
|
||||
* true - The message is consumed.
|
||||
* false - The message is not in our list.
|
||||
*/
|
||||
bool ScriptMqttData(void)
|
||||
{
|
||||
bool serviced = false;
|
||||
//toLog(">>> 1");
|
||||
toLog(XdrvMailbox.data);
|
||||
if (XdrvMailbox.data_len < 1 || XdrvMailbox.data_len > 256) {
|
||||
return false;
|
||||
}
|
||||
String sTopic = XdrvMailbox.topic;
|
||||
String sData = XdrvMailbox.data;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Script: MQTT Topic %s, Event %s"), XdrvMailbox.topic, XdrvMailbox.data);
|
||||
MQTT_Subscription event_item;
|
||||
//Looking for matched topic
|
||||
for (uint32_t index = 0; index < subscriptions.size(); index++) {
|
||||
event_item = subscriptions.get(index);
|
||||
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Script: Match MQTT message Topic %s with subscription topic %s"), sTopic.c_str(), event_item.Topic.c_str());
|
||||
if (sTopic.startsWith(event_item.Topic)) {
|
||||
//This topic is subscribed by us, so serve it
|
||||
serviced = true;
|
||||
String value;
|
||||
if (event_item.Key.length() == 0) { //If did not specify Key
|
||||
value = sData;
|
||||
} else { //If specified Key, need to parse Key/Value from JSON data
|
||||
StaticJsonBuffer<400> jsonBuf;
|
||||
JsonObject& jsonData = jsonBuf.parseObject(sData);
|
||||
String key1 = event_item.Key;
|
||||
String key2;
|
||||
if (!jsonData.success()) break; //Failed to parse JSON data, ignore this message.
|
||||
int dot;
|
||||
if ((dot = key1.indexOf('.')) > 0) {
|
||||
key2 = key1.substring(dot+1);
|
||||
key1 = key1.substring(0, dot);
|
||||
if (!jsonData[key1][key2].success()) break; //Failed to get the key/value, ignore this message.
|
||||
value = (const char *)jsonData[key1][key2];
|
||||
} else {
|
||||
if (!jsonData[key1].success()) break;
|
||||
value = (const char *)jsonData[key1];
|
||||
}
|
||||
}
|
||||
value.trim();
|
||||
//Create an new event. Cannot directly call RulesProcessEvent().
|
||||
//snprintf_P(event_data, sizeof(event_data), PSTR("%s=%s"), event_item.Event.c_str(), value.c_str());
|
||||
char sbuffer[128];
|
||||
snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=%s\n"), event_item.Event.c_str(), value.c_str());
|
||||
//toLog(sbuffer);
|
||||
execute_script(sbuffer);
|
||||
}
|
||||
}
|
||||
return serviced;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
/*
|
||||
* Subscribe a MQTT topic (with or without key) and assign an event name to it
|
||||
* Command Subscribe format:
|
||||
* Subscribe <event_name>, <topic> [, <key>]
|
||||
* This command will subscribe a <topic> and give it an event name <event_name>.
|
||||
* The optional parameter <key> is for parse the specified key/value from MQTT message
|
||||
* payload with JSON format.
|
||||
* Subscribe
|
||||
* Subscribe command without any parameter will list all topics currently subscribed.
|
||||
* Input:
|
||||
* data - A char buffer with all the parameters
|
||||
* data_len - Length of the parameters
|
||||
* Return:
|
||||
* A string include subscribed event, topic and key.
|
||||
*/
|
||||
String ScriptSubscribe(const char *data, int data_len)
|
||||
{
|
||||
MQTT_Subscription subscription_item;
|
||||
String events;
|
||||
if (data_len > 0) {
|
||||
char parameters[data_len+1];
|
||||
memcpy(parameters, data, data_len);
|
||||
parameters[data_len] = '\0';
|
||||
String event_name, topic, key;
|
||||
|
||||
char * pos = strtok(parameters, ",");
|
||||
if (pos) {
|
||||
event_name = Trim(pos);
|
||||
pos = strtok(nullptr, ",");
|
||||
if (pos) {
|
||||
topic = Trim(pos);
|
||||
pos = strtok(nullptr, ",");
|
||||
if (pos) {
|
||||
key = Trim(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Script: Subscribe command with parameters: %s, %s, %s."), event_name.c_str(), topic.c_str(), key.c_str());
|
||||
//event_name.toUpperCase();
|
||||
if (event_name.length() > 0 && topic.length() > 0) {
|
||||
//Search all subscriptions
|
||||
for (uint32_t index=0; index < subscriptions.size(); index++) {
|
||||
if (subscriptions.get(index).Event.equals(event_name)) {
|
||||
//If find exists one, remove it.
|
||||
String stopic = subscriptions.get(index).Topic + "/#";
|
||||
MqttUnsubscribe(stopic.c_str());
|
||||
subscriptions.remove(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Add "/#" to the topic
|
||||
if (!topic.endsWith("#")) {
|
||||
if (topic.endsWith("/")) {
|
||||
topic.concat("#");
|
||||
} else {
|
||||
topic.concat("/#");
|
||||
}
|
||||
}
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Script: New topic: %s."), topic.c_str());
|
||||
//MQTT Subscribe
|
||||
subscription_item.Event = event_name;
|
||||
subscription_item.Topic = topic.substring(0, topic.length() - 2); //Remove "/#" so easy to match
|
||||
subscription_item.Key = key;
|
||||
subscriptions.add(subscription_item);
|
||||
|
||||
MqttSubscribe(topic.c_str());
|
||||
events.concat(event_name + "," + topic
|
||||
+ (key.length()>0 ? "," : "")
|
||||
+ key);
|
||||
} else {
|
||||
events = D_JSON_WRONG_PARAMETERS;
|
||||
}
|
||||
} else {
|
||||
//If did not specify the event name, list all subscribed event
|
||||
for (uint32_t index=0; index < subscriptions.size(); index++) {
|
||||
subscription_item = subscriptions.get(index);
|
||||
events.concat(subscription_item.Event + "," + subscription_item.Topic
|
||||
+ (subscription_item.Key.length()>0 ? "," : "")
|
||||
+ subscription_item.Key + "; ");
|
||||
}
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
/*
|
||||
* Unsubscribe specified MQTT event. If no event specified, Unsubscribe all.
|
||||
* Command Unsubscribe format:
|
||||
* Unsubscribe [<event_name>]
|
||||
* Input:
|
||||
* data - Event name
|
||||
* data_len - Length of the parameters
|
||||
* Return:
|
||||
* list all the events unsubscribed.
|
||||
*/
|
||||
String ScriptUnsubscribe(const char * data, int data_len)
|
||||
{
|
||||
MQTT_Subscription subscription_item;
|
||||
String events;
|
||||
if (data_len > 0) {
|
||||
for (uint32_t index = 0; index < subscriptions.size(); index++) {
|
||||
subscription_item = subscriptions.get(index);
|
||||
if (subscription_item.Event.equalsIgnoreCase(data)) {
|
||||
String stopic = subscription_item.Topic + "/#";
|
||||
MqttUnsubscribe(stopic.c_str());
|
||||
events = subscription_item.Event;
|
||||
subscriptions.remove(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//If did not specify the event name, unsubscribe all event
|
||||
String stopic;
|
||||
while (subscriptions.size() > 0) {
|
||||
events.concat(subscriptions.get(0).Event + "; ");
|
||||
stopic = subscriptions.get(0).Topic + "/#";
|
||||
MqttUnsubscribe(stopic.c_str());
|
||||
subscriptions.remove(0);
|
||||
}
|
||||
}
|
||||
return events;
|
||||
}
|
||||
#endif // SUPPORT_MQTT_EVENT
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
@ -3068,6 +3283,7 @@ bool Xdrv10(uint8_t function)
|
|||
glob_script_mem.script_pram_size=MAX_RULE_MEMS*10;
|
||||
|
||||
#ifdef USE_24C256
|
||||
#ifndef USE_SCRIPT_FATFS
|
||||
if (i2c_flg) {
|
||||
if (I2cDevice(EEPROM_ADDRESS)) {
|
||||
// found 32kb eeprom
|
||||
|
@ -3089,6 +3305,7 @@ bool Xdrv10(uint8_t function)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_SCRIPT_FATFS
|
||||
if (SD.begin(USE_SCRIPT_FATFS)) {
|
||||
|
@ -3146,7 +3363,7 @@ bool Xdrv10(uint8_t function)
|
|||
break;
|
||||
case FUNC_SET_POWER:
|
||||
case FUNC_RULES_PROCESS:
|
||||
if (bitRead(Settings.rule_enabled, 0) && mqtt_data[0]) Run_Scripter(">E",2,mqtt_data);
|
||||
if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">E",2,mqtt_data);
|
||||
break;
|
||||
#ifdef USE_WEBSERVER
|
||||
case FUNC_WEB_ADD_BUTTON:
|
||||
|
@ -3168,6 +3385,11 @@ bool Xdrv10(uint8_t function)
|
|||
Scripter_save_pvars();
|
||||
}
|
||||
break;
|
||||
#ifdef SUPPORT_MQTT_EVENT
|
||||
case FUNC_MQTT_DATA:
|
||||
result = ScriptMqttData();
|
||||
break;
|
||||
#endif //SUPPORT_MQTT_EVENT
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue