Merge branch 'mega' into feature/ui-add-optional-tooltip-for-input-controls

This commit is contained in:
Ton Huisman
2021-05-19 20:42:15 +02:00
committed by GitHub
90 changed files with 2991 additions and 1208 deletions
+22
View File
@@ -111,6 +111,28 @@ This is often used to perform the initial configuration like connecting to the l
Can also be set via the command ``WiFiAPKey``.
Don't force /setup in AP-Mode
-----------------------------
Allow optional usage of ESPEasy without WIFI avaiable.
When checked you can use ESPEasy in AP-Mode without beeing forced to ``/setup``.
Do Not Start AP
---------------
Usually the AP will be started when no WiFi is defined, or the defined one cannot be found.
This flag may prevent to start an AP.
Since this flag can lock out a user, there is a restricted command to uncheck this.
``WifiAllowAP`` will uncheck this flag in the settings until a reboot.
If the settings are saved, this flag will remain unchecked.
N.B. Restricted means, not accepted from a remote source, only local or via serial.
Custom Build WiFi credentials
-----------------------------
+16 -1
View File
@@ -203,7 +203,16 @@
:red:`Internal`","
Add string to log
``LogEntry,<string>``"
``LogEntry,<string>[,<level>]``
``<level>`` is optional and can be any of these (numeric) values:
- 1 = ERROR
- 2 = INFO (default)
- 3 = DEBUG
- 4 = DEBUG_DEV
When a ``<level>`` is provided, it will be present in the log output if the 'Tolerant last parameter' Advanced setting is enabled."
"
LogPortStatus","
:red:`Internal`","
@@ -486,6 +495,12 @@
``WifiAPKey,<WPA key>``"
"
WifiAllowAP","
:red:`Internal`","
Uncheck the setting to prevent starting AP when unable to connect to a network.
``WifiAllowAP``"
"
WifiAPMode","
:red:`Internal`","
Force the unit into AP mode.
+55
View File
@@ -0,0 +1,55 @@
SparkFun License Information
============================
SparkFun uses two different licenses for our files — one for hardware and one for code.
Hardware
---------
**SparkFun hardware is released under [Creative Commons Share-alike 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/).**
Note: This is a human-readable summary of (and not a substitute for) the [license](http://creativecommons.org/licenses/by-sa/4.0/legalcode).
You are free to:
Share — copy and redistribute the material in any medium or format
Adapt — remix, transform, and build upon the material
for any purpose, even commercially.
The licensor cannot revoke these freedoms as long as you follow the license terms.
Under the following terms:
Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
Notices:
You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation.
No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.
Code
--------
**SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT).**
The MIT License (MIT)
Copyright (c) 2016 SparkFun Electronics
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+569
View File
@@ -0,0 +1,569 @@
/*
This is a library written for the AMS AS7265x Spectral Triad (Moonlight)
SparkFun sells these at its website: www.sparkfun.com
Do you like this library? Help support SparkFun. Buy a board!
https://www.sparkfun.com/products/15050
Written by Nathan Seidle & Kevin Kuwata @ SparkFun Electronics, October 25th, 2018
The Spectral Triad is a three sensor platform to do 18-channel spectroscopy.
https://github.com/sparkfun/SparkFun_AS7265X_Arduino_Library
Development environment specifics:
Arduino IDE 1.8.5
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "SparkFun_AS7265X.h"
#include <Arduino.h>
//Constructor
AS7265X::AS7265X()
{
}
//Initializes the sensor with basic settings
//Returns false if sensor is not detected
boolean AS7265X::begin(TwoWire &wirePort)
{
_i2cPort = &wirePort;
_i2cPort->begin(); //This resets any setClock() the user may have done
if (isConnected() == false) return (false); //Check for sensor presence
//Check to see if both slaves are detected
uint8_t value = virtualReadRegister(AS7265X_DEV_SELECT_CONTROL);
if ( (value & 0b00110000) == 0) return (false); //Test if Slave1 and 2 are detected. If not, bail.
setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_12_5MA, AS7265x_LED_WHITE);
setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_12_5MA, AS7265x_LED_IR);
setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_12_5MA, AS7265x_LED_UV);
disableBulb(AS7265x_LED_WHITE); //Turn off bulb to avoid heating sensor
disableBulb(AS7265x_LED_IR);
disableBulb(AS7265x_LED_UV);
setIndicatorCurrent(AS7265X_INDICATOR_CURRENT_LIMIT_8MA); //Set to 8mA (maximum)
enableIndicator();
setIntegrationCycles(49); //50 * 2.8ms = 140ms. 0 to 255 is valid.
//If you use Mode 2 or 3 (all the colors) then integration time is double. 140*2 = 280ms between readings.
setGain(AS7265X_GAIN_64X); //Set gain to 64x
setMeasurementMode(AS7265X_MEASUREMENT_MODE_6CHAN_ONE_SHOT); //One-shot reading of VBGYOR
enableInterrupt();
return (true); //We're all setup!
}
uint8_t AS7265X::getDeviceType()
{
return(virtualReadRegister(AS7265X_HW_VERSION_HIGH));
}
uint8_t AS7265X::getHardwareVersion()
{
return(virtualReadRegister(AS7265X_HW_VERSION_LOW));
}
uint8_t AS7265X::getMajorFirmwareVersion()
{
virtualWriteRegister(AS7265X_FW_VERSION_HIGH, 0x01); //Set to 0x01 for Major
virtualWriteRegister(AS7265X_FW_VERSION_LOW, 0x01); //Set to 0x01 for Major
return(virtualReadRegister(AS7265X_FW_VERSION_LOW));
}
uint8_t AS7265X::getPatchFirmwareVersion()
{
virtualWriteRegister(AS7265X_FW_VERSION_HIGH, 0x02); //Set to 0x02 for Patch
virtualWriteRegister(AS7265X_FW_VERSION_LOW, 0x02); //Set to 0x02 for Patch
return(virtualReadRegister(AS7265X_FW_VERSION_LOW));
}
uint8_t AS7265X::getBuildFirmwareVersion()
{
virtualWriteRegister(AS7265X_FW_VERSION_HIGH, 0x03); //Set to 0x03 for Build
virtualWriteRegister(AS7265X_FW_VERSION_LOW, 0x03); //Set to 0x03 for Build
return(virtualReadRegister(AS7265X_FW_VERSION_LOW));
}
//Returns true if I2C device ack's
boolean AS7265X::isConnected()
{
_i2cPort->beginTransmission((uint8_t)AS7265X_ADDR);
if (_i2cPort->endTransmission() != 0)
return (false); //Sensor did not ACK
return (true);
}
//Tells IC to take all channel measurements and polls for data ready flag
void AS7265X::takeMeasurements()
{
setMeasurementMode(AS7265X_MEASUREMENT_MODE_6CHAN_ONE_SHOT); //Set mode to all 6-channels, one-shot
//Wait for data to be ready
while (dataAvailable() == false) delay(AS7265X_POLLING_DELAY);
//Readings can now be accessed via getCalibratedA(), getJ(), etc
}
//Turns on all bulbs, takes measurements of all channels, turns off all bulbs
void AS7265X::takeMeasurementsWithBulb()
{
enableBulb(AS7265x_LED_WHITE);
enableBulb(AS7265x_LED_IR);
enableBulb(AS7265x_LED_UV);
takeMeasurements();
disableBulb(AS7265x_LED_WHITE); //Turn off bulb to avoid heating sensor
disableBulb(AS7265x_LED_IR);
disableBulb(AS7265x_LED_UV);
}
//Get the various color readings
uint16_t AS7265X::getG() {
return (getChannel(AS7265X_R_G_A, AS72652_VISIBLE));
}
uint16_t AS7265X::getH() {
return (getChannel(AS7265X_S_H_B, AS72652_VISIBLE));
}
uint16_t AS7265X::getI() {
return (getChannel(AS7265X_T_I_C, AS72652_VISIBLE));
}
uint16_t AS7265X::getJ() {
return (getChannel(AS7265X_U_J_D, AS72652_VISIBLE));
}
uint16_t AS7265X::getK() {
return (getChannel(AS7265X_V_K_E, AS72652_VISIBLE));
}
uint16_t AS7265X::getL() {
return (getChannel(AS7265X_W_L_F, AS72652_VISIBLE));
}
//Get the various NIR readings
uint16_t AS7265X::getR() {
return (getChannel(AS7265X_R_G_A, AS72651_NIR));
}
uint16_t AS7265X::getS() {
return (getChannel(AS7265X_S_H_B, AS72651_NIR));
}
uint16_t AS7265X::getT() {
return (getChannel(AS7265X_T_I_C, AS72651_NIR));
}
uint16_t AS7265X::getU() {
return (getChannel(AS7265X_U_J_D, AS72651_NIR));
}
uint16_t AS7265X::getV() {
return (getChannel(AS7265X_V_K_E, AS72651_NIR));
}
uint16_t AS7265X::getW() {
return (getChannel(AS7265X_W_L_F, AS72651_NIR));
}
//Get the various UV readings
uint16_t AS7265X::getA() {
return (getChannel(AS7265X_R_G_A, AS72653_UV));
}
uint16_t AS7265X::getB() {
return (getChannel(AS7265X_S_H_B, AS72653_UV));
}
uint16_t AS7265X::getC() {
return (getChannel(AS7265X_T_I_C, AS72653_UV));
}
uint16_t AS7265X::getD() {
return (getChannel(AS7265X_U_J_D, AS72653_UV));
}
uint16_t AS7265X::getE() {
return (getChannel(AS7265X_V_K_E, AS72653_UV));
}
uint16_t AS7265X::getF() {
return (getChannel(AS7265X_W_L_F, AS72653_UV));
}
//A the 16-bit value stored in a given channel registerReturns
uint16_t AS7265X::getChannel(uint8_t channelRegister, uint8_t device)
{
selectDevice(device);
uint16_t colorData = virtualReadRegister(channelRegister) << 8; //High uint8_t
colorData |= virtualReadRegister(channelRegister + 1); //Low uint8_t
return (colorData);
}
//Returns the various calibration data
float AS7265X::getCalibratedA() {
return (getCalibratedValue(AS7265X_R_G_A_CAL, AS72653_UV));
}
float AS7265X::getCalibratedB() {
return (getCalibratedValue(AS7265X_S_H_B_CAL, AS72653_UV));
}
float AS7265X::getCalibratedC() {
return (getCalibratedValue(AS7265X_T_I_C_CAL, AS72653_UV));
}
float AS7265X::getCalibratedD() {
return (getCalibratedValue(AS7265X_U_J_D_CAL, AS72653_UV));
}
float AS7265X::getCalibratedE() {
return (getCalibratedValue(AS7265X_V_K_E_CAL, AS72653_UV));
}
float AS7265X::getCalibratedF() {
return (getCalibratedValue(AS7265X_W_L_F_CAL, AS72653_UV));
}
//Returns the various calibration data
float AS7265X::getCalibratedG() {
return (getCalibratedValue(AS7265X_R_G_A_CAL, AS72652_VISIBLE));
}
float AS7265X::getCalibratedH() {
return (getCalibratedValue(AS7265X_S_H_B_CAL, AS72652_VISIBLE));
}
float AS7265X::getCalibratedI() {
return (getCalibratedValue(AS7265X_T_I_C_CAL, AS72652_VISIBLE));
}
float AS7265X::getCalibratedJ() {
return (getCalibratedValue(AS7265X_U_J_D_CAL, AS72652_VISIBLE));
}
float AS7265X::getCalibratedK() {
return (getCalibratedValue(AS7265X_V_K_E_CAL, AS72652_VISIBLE));
}
float AS7265X::getCalibratedL() {
return (getCalibratedValue(AS7265X_W_L_F_CAL, AS72652_VISIBLE));
}
float AS7265X::getCalibratedR() {
return (getCalibratedValue(AS7265X_R_G_A_CAL, AS72651_NIR));
}
float AS7265X::getCalibratedS() {
return (getCalibratedValue(AS7265X_S_H_B_CAL, AS72651_NIR));
}
float AS7265X::getCalibratedT() {
return (getCalibratedValue(AS7265X_T_I_C_CAL, AS72651_NIR));
}
float AS7265X::getCalibratedU() {
return (getCalibratedValue(AS7265X_U_J_D_CAL, AS72651_NIR));
}
float AS7265X::getCalibratedV() {
return (getCalibratedValue(AS7265X_V_K_E_CAL, AS72651_NIR));
}
float AS7265X::getCalibratedW() {
return (getCalibratedValue(AS7265X_W_L_F_CAL, AS72651_NIR));
}
//Given an address, read four bytes and return the floating point calibrated value
float AS7265X::getCalibratedValue(uint8_t calAddress, uint8_t device)
{
selectDevice(device);
uint8_t b0, b1, b2, b3;
b0 = virtualReadRegister(calAddress + 0);
b1 = virtualReadRegister(calAddress + 1);
b2 = virtualReadRegister(calAddress + 2);
b3 = virtualReadRegister(calAddress + 3);
//Channel calibrated values are stored big-endian
uint32_t calBytes = 0;
calBytes |= ((uint32_t)b0 << (8 * 3));
calBytes |= ((uint32_t)b1 << (8 * 2));
calBytes |= ((uint32_t)b2 << (8 * 1));
calBytes |= ((uint32_t)b3 << (8 * 0));
return (convertBytesToFloat(calBytes));
}
//Given 4 bytes returns the floating point value
float AS7265X::convertBytesToFloat(uint32_t myLong)
{
float myFloat;
memcpy(&myFloat, &myLong, 4); //Copy bytes into a float
return (myFloat);
}
//Mode 0: 4 channels out of 6 (see datasheet)
//Mode 1: Different 4 channels out of 6 (see datasheet)
//Mode 2: All 6 channels continuously
//Mode 3: One-shot reading of all channels
void AS7265X::setMeasurementMode(uint8_t mode)
{
if (mode > 0b11) mode = 0b11; //Error check
//Read, mask/set, write
uint8_t value = virtualReadRegister(AS7265X_CONFIG); //Read
value &= 0b11110011; //Clear BANK bits
value |= (mode << 2); //Set BANK bits with user's choice
virtualWriteRegister(AS7265X_CONFIG, value); //Write
}
//Sets the gain value
//Gain 0: 1x (power-on default)
//Gain 1: 3.7x
//Gain 2: 16x
//Gain 3: 64x
void AS7265X::setGain(uint8_t gain)
{
if (gain > 0b11) gain = 0b11;
//Read, mask/set, write
uint8_t value = virtualReadRegister(AS7265X_CONFIG); //Read
value &= 0b11001111; //Clear GAIN bits
value |= (gain << 4); //Set GAIN bits with user's choice
virtualWriteRegister(AS7265X_CONFIG, value); //Write
}
//Sets the integration cycle amount
//Give this function a byte from 0 to 255.
//Time will be 2.8ms * [integration cycles + 1]
void AS7265X::setIntegrationCycles(uint8_t cycleValue)
{
virtualWriteRegister(AS7265X_INTERGRATION_TIME, cycleValue); //Write
}
void AS7265X::enableInterrupt()
{
//Read, mask/set, write
uint8_t value = virtualReadRegister(AS7265X_CONFIG); //Read
value |= (1 << 6); //Set INT bit
virtualWriteRegister(AS7265X_CONFIG, value); //Write
}
//Disables the interrupt pin
void AS7265X::disableInterrupt()
{
//Read, mask/set, write
uint8_t value = virtualReadRegister(AS7265X_CONFIG); //Read
value &= ~(1 << 6); //Clear INT bit
virtualWriteRegister(AS7265X_CONFIG, value); //Write
}
//Checks to see if DRDY flag is set in the control setup register
boolean AS7265X::dataAvailable()
{
uint8_t value = virtualReadRegister(AS7265X_CONFIG);
return (value & (1 << 1)); //Bit 1 is DATA_RDY
}
//Enable the LED or bulb on a given device
void AS7265X::enableBulb(uint8_t device)
{
selectDevice(device);
//Read, mask/set, write
uint8_t value = virtualReadRegister(AS7265X_LED_CONFIG);
value |= (1 << 3); //Set the bit
virtualWriteRegister(AS7265X_LED_CONFIG, value);
}
//Disable the LED or bulb on a given device
void AS7265X::disableBulb(uint8_t device)
{
selectDevice(device);
//Read, mask/set, write
uint8_t value = virtualReadRegister(AS7265X_LED_CONFIG);
value &= ~(1 << 3); //Clear the bit
virtualWriteRegister(AS7265X_LED_CONFIG, value);
}
//Set the current limit of bulb/LED.
//Current 0: 12.5mA
//Current 1: 25mA
//Current 2: 50mA
//Current 3: 100mA
void AS7265X::setBulbCurrent(uint8_t current, uint8_t device)
{
selectDevice(device);
// set the current
if (current > 0b11) current = 0b11; //Limit to two bits
uint8_t value = virtualReadRegister(AS7265X_LED_CONFIG); //Read
value &= 0b11001111; //Clear ICL_DRV bits
value |= (current << 4); //Set ICL_DRV bits with user's choice
virtualWriteRegister(AS7265X_LED_CONFIG, value); //Write
}
//As we read various registers we have to point at the master or first/second slave
void AS7265X::selectDevice(uint8_t device) {
//Set the bits 0:1. Just overwrite whatever is there because masking in the correct value doesn't work.
virtualWriteRegister(AS7265X_DEV_SELECT_CONTROL, device);
//This fails
//uint8_t value = virtualReadRegister(AS7265X_DEV_SELECT_CONTROL);
//value &= 0b11111100; //Clear lower two bits
//if(device < 3) value |= device; //Set the bits
//virtualWriteRegister(AS7265X_DEV_SELECT_CONTROL, value);
}
//Enable the onboard indicator LED
void AS7265X::enableIndicator()
{
//Read, mask/set, write
uint8_t value = virtualReadRegister(AS7265X_LED_CONFIG);
value |= (1 << 0); //Set the bit
selectDevice(AS72651_NIR);
virtualWriteRegister(AS7265X_LED_CONFIG, value);
}
//Disable the onboard indicator LED
void AS7265X::disableIndicator()
{
//Read, mask/set, write
uint8_t value = virtualReadRegister(AS7265X_LED_CONFIG);
value &= ~(1 << 0); //Clear the bit
selectDevice(AS72651_NIR);
virtualWriteRegister(AS7265X_LED_CONFIG, value);
}
//Set the current limit of onboard LED. Default is max 8mA = 0b11.
void AS7265X::setIndicatorCurrent(uint8_t current)
{
if (current > 0b11) current = 0b11;
//Read, mask/set, write
uint8_t value = virtualReadRegister(AS7265X_LED_CONFIG); //Read
value &= 0b11111001; //Clear ICL_IND bits
value |= (current << 1); //Set ICL_IND bits with user's choice
selectDevice(AS72651_NIR);
virtualWriteRegister(AS7265X_LED_CONFIG, value); //Write
}
//Returns the temperature of a given device in C
uint8_t AS7265X::getTemperature(uint8_t deviceNumber)
{
selectDevice(deviceNumber);
return (virtualReadRegister(AS7265X_DEVICE_TEMP));
}
//Returns an average of all the sensor temps in C
float AS7265X::getTemperatureAverage()
{
float average = 0;
for(uint8_t x = 0 ; x < 3 ; x++)
average += getTemperature(x);
return (average/3);
}
//Does a soft reset
//Give sensor at least 1000ms to reset
void AS7265X::softReset()
{
//Read, mask/set, write
uint8_t value = virtualReadRegister(AS7265X_CONFIG); //Read
value |= (1 << 7); //Set RST bit, automatically cleared after reset
virtualWriteRegister(AS7265X_CONFIG, value); //Write
}
//Read a virtual register from the AS7265x
uint8_t AS7265X::virtualReadRegister(uint8_t virtualAddr)
{
uint8_t status;
//Do a prelim check of the read register
status = readRegister(AS7265X_STATUS_REG);
if ((status & AS7265X_RX_VALID) != 0) //There is data to be read
{
uint8_t incoming = readRegister(AS7265X_READ_REG); //Read the byte but do nothing with it
}
//Wait for WRITE flag to clear
while (1)
{
status = readRegister(AS7265X_STATUS_REG);
if ((status & AS7265X_TX_VALID) == 0) break; // If TX bit is clear, it is ok to write
delay(AS7265X_POLLING_DELAY);
}
// Send the virtual register address (bit 7 should be 0 to indicate we are reading a register).
writeRegister(AS7265X_WRITE_REG, virtualAddr);
//Wait for READ flag to be set
while (1)
{
status = readRegister(AS7265X_STATUS_REG);
if ((status & AS7265X_RX_VALID) != 0) break; // Read data is ready.
delay(AS7265X_POLLING_DELAY);
}
uint8_t incoming = readRegister(AS7265X_READ_REG);
return (incoming);
}
//Write to a virtual register in the AS726x
void AS7265X::virtualWriteRegister(uint8_t virtualAddr, uint8_t dataToWrite)
{
uint8_t status;
//Wait for WRITE register to be empty
while (1)
{
status = readRegister(AS7265X_STATUS_REG);
if ((status & AS7265X_TX_VALID) == 0) break; // No inbound TX pending at slave. Okay to write now.
delay(AS7265X_POLLING_DELAY);
}
// Send the virtual register address (setting bit 7 to indicate we are writing to a register).
writeRegister(AS7265X_WRITE_REG, (virtualAddr | 1<<7));
//Wait for WRITE register to be empty
while (1)
{
status = readRegister(AS7265X_STATUS_REG);
if ((status & AS7265X_TX_VALID) == 0) break; // No inbound TX pending at slave. Okay to write now.
delay(AS7265X_POLLING_DELAY);
}
// Send the data to complete the operation.
writeRegister(AS7265X_WRITE_REG, dataToWrite);
}
//Reads from a give location from the AS726x
uint8_t AS7265X::readRegister(uint8_t addr)
{
_i2cPort->beginTransmission(AS7265X_ADDR);
_i2cPort->write(addr);
if (_i2cPort->endTransmission() != 0)
{
//Serial.println("No ack!");
return (0); //Device failed to ack
}
_i2cPort->requestFrom((uint8_t)AS7265X_ADDR, (uint8_t)1);
if (_i2cPort->available()) {
return (_i2cPort->read());
}
//Serial.println("No ack!");
return (0); //Device failed to respond
}
//Write a value to a spot in the AS726x
boolean AS7265X::writeRegister(uint8_t addr, uint8_t val)
{
_i2cPort->beginTransmission(AS7265X_ADDR);
_i2cPort->write(addr);
_i2cPort->write(val);
if (_i2cPort->endTransmission() != 0)
{
//Serial.println("No ack!");
return (false); //Device failed to ack
}
return (true);
}
+206
View File
@@ -0,0 +1,206 @@
/*
This is a library written for the AMS AS7265x Spectral Triad (Moonlight)
SparkFun sells these at its website: www.sparkfun.com
Do you like this library? Help support SparkFun. Buy a board!
https://www.sparkfun.com/products/15050
Written by Nathan Seidle & Kevin Kuwata @ SparkFun Electronics, October 25th, 2018
The Spectral Triad is a three sensor platform to do 18-channel spectroscopy.
https://github.com/sparkfun/SparkFun_AS7265X_Arduino_Library
Development environment specifics:
Arduino IDE 1.8.5
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SPARKFUN_AS7265X_H
#define _SPARKFUN_AS7265X_H
#include <Arduino.h>
#include <Wire.h>
#define AS7265X_ADDR 0x49 //7-bit unshifted default I2C Address
#define AS7265X_STATUS_REG 0x00
#define AS7265X_WRITE_REG 0X01
#define AS7265X_READ_REG 0x02
#define AS7265X_TX_VALID 0x02
#define AS7265X_RX_VALID 0x01
//Register addresses
#define AS7265X_HW_VERSION_HIGH 0x00
#define AS7265X_HW_VERSION_LOW 0x01
#define AS7265X_FW_VERSION_HIGH 0x02
#define AS7265X_FW_VERSION_LOW 0x03
#define AS7265X_CONFIG 0x04
#define AS7265X_INTERGRATION_TIME 0x05
#define AS7265X_DEVICE_TEMP 0x06
#define AS7265X_LED_CONFIG 0x07
//Raw channel registers
#define AS7265X_R_G_A 0x08
#define AS7265X_S_H_B 0x0A
#define AS7265X_T_I_C 0x0C
#define AS7265X_U_J_D 0x0E
#define AS7265X_V_K_E 0x10
#define AS7265X_W_L_F 0x12
//Calibrated channel registers
#define AS7265X_R_G_A_CAL 0x14
#define AS7265X_S_H_B_CAL 0x18
#define AS7265X_T_I_C_CAL 0x1C
#define AS7265X_U_J_D_CAL 0x20
#define AS7265X_V_K_E_CAL 0x24
#define AS7265X_W_L_F_CAL 0x28
#define AS7265X_DEV_SELECT_CONTROL 0x4F
#define AS7265X_COEF_DATA_0 0x50
#define AS7265X_COEF_DATA_1 0x51
#define AS7265X_COEF_DATA_2 0x52
#define AS7265X_COEF_DATA_3 0x53
#define AS7265X_COEF_DATA_READ 0x54
#define AS7265X_COEF_DATA_WRITE 0x55
//Settings
#define AS7265X_POLLING_DELAY 5 //Amount of ms to wait between checking for virtual register changes
#define AS72651_NIR 0x00
#define AS72652_VISIBLE 0x01
#define AS72653_UV 0x02
#define AS7265x_LED_WHITE 0x00 //White LED is connected to x51
#define AS7265x_LED_IR 0x01 //IR LED is connected to x52
#define AS7265x_LED_UV 0x02 //UV LED is connected to x53
#define AS7265X_LED_CURRENT_LIMIT_12_5MA 0b00
#define AS7265X_LED_CURRENT_LIMIT_25MA 0b01
#define AS7265X_LED_CURRENT_LIMIT_50MA 0b10
#define AS7265X_LED_CURRENT_LIMIT_100MA 0b11
#define AS7265X_INDICATOR_CURRENT_LIMIT_1MA 0b00
#define AS7265X_INDICATOR_CURRENT_LIMIT_2MA 0b01
#define AS7265X_INDICATOR_CURRENT_LIMIT_4MA 0b10
#define AS7265X_INDICATOR_CURRENT_LIMIT_8MA 0b11
#define AS7265X_GAIN_1X 0b00
#define AS7265X_GAIN_37X 0b01
#define AS7265X_GAIN_16X 0b10
#define AS7265X_GAIN_64X 0b11
#define AS7265X_MEASUREMENT_MODE_4CHAN 0b00
#define AS7265X_MEASUREMENT_MODE_4CHAN_2 0b01
#define AS7265X_MEASUREMENT_MODE_6CHAN_CONTINUOUS 0b10
#define AS7265X_MEASUREMENT_MODE_6CHAN_ONE_SHOT 0b11
class AS7265X {
public:
AS7265X();
boolean begin(TwoWire &wirePort = Wire);
boolean isConnected(); //Checks if sensor ack's the I2C request
uint8_t getDeviceType();
uint8_t getHardwareVersion();
uint8_t getMajorFirmwareVersion();
uint8_t getPatchFirmwareVersion();
uint8_t getBuildFirmwareVersion();
uint8_t getTemperature(uint8_t deviceNumber = 0); //Get temp in C of the master IC
float getTemperatureAverage(); //Get average of all three ICs
void takeMeasurements();
void takeMeasurementsWithBulb();
void enableIndicator(); //Blue status LED
void disableIndicator();
void enableBulb(uint8_t device);
void disableBulb(uint8_t device);
void setGain(uint8_t gain); //1 to 64x
void setMeasurementMode(uint8_t mode); //4 channel, other 4 channel, 6 chan, or 6 chan one shot
void setIntegrationCycles(uint8_t cycleValue);
void setBulbCurrent(uint8_t current, uint8_t device); //
void setIndicatorCurrent(uint8_t current); //0 to 8mA
void enableInterrupt();
void disableInterrupt();
void softReset();
boolean dataAvailable(); //Returns true when data is available
//Returns the various calibration data
float getCalibratedA();
float getCalibratedB();
float getCalibratedC();
float getCalibratedD();
float getCalibratedE();
float getCalibratedF();
float getCalibratedG();
float getCalibratedH();
float getCalibratedI();
float getCalibratedJ();
float getCalibratedK();
float getCalibratedL();
float getCalibratedR();
float getCalibratedS();
float getCalibratedT();
float getCalibratedU();
float getCalibratedV();
float getCalibratedW();
//Get the various raw readings
uint16_t getA();
uint16_t getB();
uint16_t getC();
uint16_t getD();
uint16_t getE();
uint16_t getF();
uint16_t getG();
uint16_t getH();
uint16_t getI();
uint16_t getJ();
uint16_t getK();
uint16_t getL();
uint16_t getR();
uint16_t getS();
uint16_t getT();
uint16_t getU();
uint16_t getV();
uint16_t getW();
private:
TwoWire *_i2cPort;
uint16_t getChannel(uint8_t channelRegister, uint8_t device);
float getCalibratedValue(uint8_t calAddress, uint8_t device);
float convertBytesToFloat(uint32_t myLong);
void selectDevice(uint8_t device); //Change between the x51, x52, or x53 for data and settings
uint8_t virtualReadRegister(uint8_t virtualAddr);
void virtualWriteRegister(uint8_t virtualAddr, uint8_t dataToWrite);
uint8_t readRegister(uint8_t addr);
boolean writeRegister(uint8_t addr, uint8_t val);
};
#endif
+17 -2
View File
@@ -5,7 +5,11 @@
*/
#include "PubSubClient.h"
#include "Arduino.h"
#include <Arduino.h>
#ifdef ESP32
#include <WiFiClient.h>
#endif
PubSubClient::PubSubClient() {
this->_state = MQTT_DISCONNECTED;
@@ -128,9 +132,19 @@ boolean PubSubClient::connect(const char *id, const char *user, const char *pass
result = 1;
} else {
if (domain.length() != 0) {
#ifdef ESP32
WiFiClient* wfc = (WiFiClient*)_client;
result = wfc->connect(this->domain.c_str(), this->port, ESP32_CONNECTION_TIMEOUT);
#else
result = _client->connect(this->domain.c_str(), this->port);
#endif
} else {
#ifdef ESP32
WiFiClient* wfc = (WiFiClient*)_client;
result = wfc->connect(this->ip, this->port, ESP32_CONNECTION_TIMEOUT);
#else
result = _client->connect(this->ip, this->port);
#endif
}
}
if (result == 1) {
@@ -194,6 +208,7 @@ boolean PubSubClient::connect(const char *id, const char *user, const char *pass
write(MQTTCONNECT,buffer,length-MQTT_MAX_HEADER_SIZE);
lastInActivity = lastOutActivity = millis();
pingOutstanding = false; // See: https://github.com/knolleary/pubsubclient/pull/802
while (!_client->available()) {
delay(0); // Prevent watchdog crashes
@@ -445,7 +460,7 @@ boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigne
}
boolean PubSubClient::publish_P(const char* topic, const char* payload, boolean retained) {
size_t plength = (payload != nullptr) ? strlen(payload) : 0;
size_t plength = (payload != nullptr) ? strlen_P(payload) : 0;
return publish_P(topic, (const uint8_t*)payload, plength, retained);
}
+9
View File
@@ -37,6 +37,15 @@
#define MQTT_SOCKET_TIMEOUT 15
#endif
// ESP32_CONNECTION_TIMEOUT : Specific case for ESP32, we need to manually provide timeout as default (-1) leads to WDT reset (after 5 seconds).
// By default (4500 milliseconds) 4,5 seconds to avoid reaching 5s default watchdog reset time.
// This is multiplied in WiFiClient.cpp (part of arduino-esp32) by 1000 inside [WiFiClient::connect] method.
// ESP8266 Arduino framework in contrast has fixed 5000ms timeout. No need to define it manually here.
// See: https://github.com/knolleary/pubsubclient/pull/842
#ifndef ESP32_CONNECTION_TIMEOUT
#define ESP32_CONNECTION_TIMEOUT 4500
#endif
// MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client
// in each write call. Needed for the Arduino Wifi Shield. Leave undefined to
// pass the entire MQTT packet in each write call.
+2 -1
View File
@@ -67,7 +67,8 @@
// See: https://github.com/letscontrolit/ESPEasy/issues/2724
#define DEFAULT_SEND_TO_HTTP_ACK false // Wait for ack with SendToHttp command.
#define DEFAULT_AP_DONT_FORCE_SETUP false // Allow optional usage of Sensor without WIFI avaiable // When set you can use the Sensor in AP-Mode without beeing forced to /setup
#define DEFAULT_AP_DONT_FORCE_SETUP false // Allow optional usage of Sensor without WIFI avaiable // When set you can use the Sensor in AP-Mode without beeing forced to /setup
#define DEFAULT_DONT_ALLOW_START_AP false // Usually the AP will be started when no WiFi is defined, or the defined one cannot be found. This flag may prevent it.
// --- Default Controller ------------------------------------------------------------------------------
#define DEFAULT_CONTROLLER false // true or false enabled or disabled, set 1st controller
+39 -632
View File
@@ -2,10 +2,10 @@
#include <Arduino.h>
#ifdef CONTINUOUS_INTEGRATION
#pragma GCC diagnostic error "-Wall"
#else
#pragma GCC diagnostic warning "-Wall"
#endif
# pragma GCC diagnostic error "-Wall"
#else // ifdef CONTINUOUS_INTEGRATION
# pragma GCC diagnostic warning "-Wall"
#endif // ifdef CONTINUOUS_INTEGRATION
// Include this as first, to make sure all defines are active during the entire compile.
// See: https://www.letscontrolit.com/forum/viewtopic.php?f=4&t=7980
@@ -13,18 +13,18 @@
#include "ESPEasy_common.h"
#ifdef USE_CUSTOM_H
// make the compiler show a warning to confirm that this file is inlcuded
#warning "**** Using Settings from Custom.h File ***"
#endif
// make the compiler show a warning to confirm that this file is inlcuded
# warning "**** Using Settings from Custom.h File ***"
#endif // ifdef USE_CUSTOM_H
// Needed due to preprocessor issues.
#ifdef PLUGIN_SET_GENERIC_ESP32
#ifndef ESP32
#define ESP32
#endif
#endif
# ifndef ESP32
# define ESP32
# endif // ifndef ESP32
#endif // ifdef PLUGIN_SET_GENERIC_ESP32
/****************************************************************************************************************************\
@@ -44,23 +44,23 @@
* Discussion : http://www.letscontrolit.com/forum/
*
* Additional information about licensing can be found at : http://www.gnu.org/licenses
\*************************************************************************************************************************/
\*************************************************************************************************************************/
// This file incorporates work covered by the following copyright and permission notice:
/****************************************************************************************************************************\
* Arduino project "Nodo" © Copyright 2010..2015 Paul Tonkes
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You received a copy of the GNU General Public License along with this program in file 'License.txt'.
*
* Voor toelichting op de licentievoorwaarden zie : http://www.gnu.org/licenses
* Uitgebreide documentatie is te vinden op : http://www.nodo-domotica.nl
* Compiler voor deze programmacode te downloaden op : http://arduino.cc
\*************************************************************************************************************************/
* Arduino project "Nodo" © Copyright 2010..2015 Paul Tonkes
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You received a copy of the GNU General Public License along with this program in file 'License.txt'.
*
* Voor toelichting op de licentievoorwaarden zie : http://www.gnu.org/licenses
* Uitgebreide documentatie is te vinden op : http://www.nodo-domotica.nl
* Compiler voor deze programmacode te downloaden op : http://arduino.cc
\*************************************************************************************************************************/
// Simple Arduino sketch for ESP module, supporting:
// =================================================================================
@@ -97,642 +97,49 @@
// Define globals before plugin sets to allow a personal override of the selected plugins
#include "ESPEasy-Globals.h"
// Must be included after all the defines, since it is using TASKS_MAX
#include "_Plugin_Helper.h"
// Plugin helper needs the defined controller sets, thus include after 'define_plugin_sets.h'
#include "src/Helpers/_CPlugin_Helper.h"
#include "src/DataStructs/ControllerSettingsStruct.h"
#include "src/DataStructs/ESPEasy_EventStruct.h"
#include "src/DataStructs/PortStatusStruct.h"
#include "src/DataStructs/ProtocolStruct.h"
#include "src/DataStructs/RTCStruct.h"
#include "src/DataStructs/SystemTimerStruct.h"
#include "src/DataStructs/TimingStats.h"
#include "src/DataStructs/tcp_cleanup.h"
#include "src/ESPEasyCore/ESPEasy_setup.h"
#include "src/ESPEasyCore/ESPEasy_loop.h"
#include "src/DataTypes/DeviceModel.h"
#include "src/DataTypes/SettingsType.h"
#include "src/ESPEasyCore/ESPEasy_Log.h"
#include "src/ESPEasyCore/ESPEasyNetwork.h"
#include "src/ESPEasyCore/ESPEasyRules.h"
#include "src/ESPEasyCore/ESPEasyWifi.h"
#include "src/ESPEasyCore/ESPEasyWifi_ProcessEvent.h"
#include "src/ESPEasyCore/Serial.h"
#include "src/Globals/Cache.h"
#include "src/Globals/CPlugins.h"
#include "src/Globals/Device.h"
#include "src/Globals/ESPEasyWiFiEvent.h"
#include "src/Globals/ESPEasy_Scheduler.h"
#include "src/Globals/ESPEasy_time.h"
#include "src/Globals/EventQueue.h"
#include "src/Globals/ExtraTaskSettings.h"
#include "src/Globals/GlobalMapPortStatus.h"
#include "src/Globals/MQTT.h"
#include "src/Globals/NetworkState.h"
#include "src/Globals/Plugins.h"
#include "src/Globals/Protocol.h"
#include "src/Globals/RTC.h"
#include "src/Globals/RamTracker.h"
#include "src/Globals/SecuritySettings.h"
#include "src/Globals/Services.h"
#include "src/Globals/Settings.h"
#include "src/Globals/Statistics.h"
#include "src/Globals/WiFi_AP_Candidates.h"
#include "src/Helpers/DeepSleep.h"
#include "src/Helpers/ESPEasyRTC.h"
#include "src/Helpers/ESPEasy_FactoryDefault.h"
#include "src/Helpers/ESPEasy_Storage.h"
#include "src/Helpers/ESPEasy_checks.h"
#include "src/Helpers/Hardware.h"
#include "src/Helpers/Memory.h"
#include "src/Helpers/Misc.h"
#include "src/Helpers/Network.h"
#include "src/Helpers/Networking.h"
#include "src/Helpers/OTA.h"
#include "src/Helpers/PeriodicalActions.h"
#include "src/Helpers/Scheduler.h"
#include "src/Helpers/StringGenerator_System.h"
#include "src/WebServer/WebServer.h"
#ifdef PHASE_LOCKED_WAVEFORM
#include <core_esp8266_waveform.h>
#endif
# include <core_esp8266_waveform.h>
#endif // ifdef PHASE_LOCKED_WAVEFORM
#if FEATURE_ADC_VCC
ADC_MODE(ADC_VCC);
#endif
#endif // if FEATURE_ADC_VCC
#ifdef CORE_POST_2_5_0
void preinit();
#endif
#ifdef CORE_POST_2_5_0
/*********************************************************************************************\
* Pre-init
* Pre-init
\*********************************************************************************************/
void preinit();
void preinit() {
// Global WiFi constructors are not called yet
// (global class instances like WiFi, Serial... are not yet initialized)..
// No global object methods or C++ exceptions can be called in here!
//The below is a static class method, which is similar to a function, so it's ok.
// The below is a static class method, which is similar to a function, so it's ok.
ESP8266WiFiClass::preinitWiFiOff();
system_phy_set_powerup_option(RF_NO_CAL);
}
#endif
/*********************************************************************************************\
* ISR call back function for handling the watchdog.
\*********************************************************************************************/
void sw_watchdog_callback(void *arg)
{
yield(); // feed the WD
++sw_watchdog_callback_count;
}
#endif // ifdef CORE_POST_2_5_0
/*********************************************************************************************\
* SETUP
\*********************************************************************************************/
void setup()
{
#ifdef ESP8266_DISABLE_EXTRA4K
disable_extra4k_at_link_time();
#endif
#ifdef PHASE_LOCKED_WAVEFORM
enablePhaseLockedWaveform();
#endif
initWiFi();
run_compiletime_checks();
#ifndef BUILD_NO_RAM_TRACKER
lowestFreeStack = getFreeStackWatermark();
lowestRAM = FreeMem();
#endif
#ifndef ESP32
// ets_isr_attach(8, sw_watchdog_callback, NULL); // Set a callback for feeding the watchdog.
#endif
// Read ADC at boot, before WiFi tries to connect.
// see https://github.com/letscontrolit/ESPEasy/issues/2646
#if FEATURE_ADC_VCC
vcc = ESP.getVcc() / 1000.0f;
#endif
#ifdef ESP8266
espeasy_analogRead(A0);
#endif
initAnalogWrite();
resetPluginTaskData();
#ifndef BUILD_NO_RAM_TRACKER
checkRAM(F("setup"));
#endif
Serial.begin(115200);
// serialPrint("\n\n\nBOOOTTT\n\n\n");
initLog();
if (SpiffsSectors() < 32)
{
serialPrintln(F("\nNo (or too small) FS area..\nSystem Halted\nPlease reflash with 128k FS minimum!"));
while (true)
delay(1);
}
emergencyReset();
String log = F("\n\n\rINIT : Booting version: ");
log += getValue(LabelType::GIT_BUILD);
log += " (";
log += getSystemLibraryString();
log += ')';
addLog(LOG_LEVEL_INFO, log);
log = F("INIT : Free RAM:");
log += FreeMem();
addLog(LOG_LEVEL_INFO, log);
readBootCause();
log = F("INIT : ");
log += getLastBootCauseString();
if (readFromRTC())
{
RTC.bootFailedCount++;
RTC.bootCounter++;
lastMixedSchedulerId_beforereboot = RTC.lastMixedSchedulerId;
readUserVarFromRTC();
if (RTC.deepSleepState != 1)
{
node_time.restoreLastKnownUnixTime(RTC.lastSysTime, RTC.deepSleepState);
}
log += F(" #");
log += RTC.bootCounter;
#ifndef BUILD_NO_DEBUG
log += F(" Last Action before Reboot: ");
log += ESPEasy_Scheduler::decodeSchedulerId(lastMixedSchedulerId_beforereboot);
log += F(" Last systime: ");
log += RTC.lastSysTime;
#endif
}
//cold boot (RTC memory empty)
else
{
initRTC();
// cold boot situation
if (lastBootCause == BOOT_CAUSE_MANUAL_REBOOT) // only set this if not set earlier during boot stage.
lastBootCause = BOOT_CAUSE_COLD_BOOT;
log = F("INIT : Cold Boot");
}
log += F(" - Restart Reason: ");
log += getResetReasonString();
RTC.deepSleepState=0;
saveToRTC();
addLog(LOG_LEVEL_INFO, log);
fileSystemCheck();
// progMemMD5check();
LoadSettings();
Settings.UseRTOSMultitasking = false; // For now, disable it, we experience heap corruption.
if (RTC.bootFailedCount > 10 && RTC.bootCounter > 10) {
byte toDisable = RTC.bootFailedCount - 10;
toDisable = disablePlugin(toDisable);
if (toDisable != 0) {
toDisable = disableController(toDisable);
}
if (toDisable != 0) {
toDisable = disableNotification(toDisable);
}
}
#ifdef HAS_ETHERNET
// This ensures, that changing WIFI OR ETHERNET MODE happens properly only after reboot. Changing without reboot would not be a good idea.
// This only works after LoadSettings();
setNetworkMedium(Settings.NetworkMedium);
#endif
if (active_network_medium == NetworkMedium_t::WIFI) {
if (!WiFi_AP_Candidates.hasKnownCredentials()) {
WiFiEventData.wifiSetup = true;
RTC.clearLastWiFi(); // Must scan all channels
// Wait until scan has finished to make sure as many as possible are found
// We're still in the setup phase, so nothing else is taking resources of the ESP.
WifiScan(false);
WiFiEventData.lastScanMoment.clear();
}
// Start an extra async scan so we can continue, but we may find more APs by scanning twice.
WifiScan(true);
}
// setWifiMode(WIFI_STA);
checkRuleSets();
// if different version, eeprom settings structure has changed. Full Reset needed
// on a fresh ESP module eeprom values are set to 255. Version results into -1 (signed int)
if (Settings.Version != VERSION || Settings.PID != ESP_PROJECT_PID)
{
// Direct Serial is allowed here, since this is only an emergency task.
serialPrint(F("\nPID:"));
serialPrintln(String(Settings.PID));
serialPrint(F("Version:"));
serialPrintln(String(Settings.Version));
serialPrintln(F("INIT : Incorrect PID or version!"));
delay(1000);
ResetFactory();
}
initSerial();
if (Settings.Build != BUILD) {
BuildFixes();
}
log = F("INIT : Free RAM:");
log += FreeMem();
addLog(LOG_LEVEL_INFO, log);
if (Settings.UseSerial && Settings.SerialLogLevel >= LOG_LEVEL_DEBUG_MORE)
Serial.setDebugOutput(true);
#ifndef BUILD_NO_RAM_TRACKER
checkRAM(F("hardwareInit"));
#endif
hardwareInit();
timermqtt_interval = 250; // Interval for checking MQTT
timerAwakeFromDeepSleep = millis();
CPluginInit();
#ifdef USES_NOTIFIER
NPluginInit();
#endif
PluginInit();
log = F("INFO : Plugins: ");
log += deviceCount + 1;
log += ' ';
log += getPluginDescriptionString();
log += " (";
log += getSystemLibraryString();
log += ')';
addLog(LOG_LEVEL_INFO, log);
if (deviceCount + 1 >= PLUGIN_MAX) {
addLog(LOG_LEVEL_ERROR, String(F("Programming error! - Increase PLUGIN_MAX (")) + deviceCount + ')');
}
clearAllCaches();
if (Settings.UseRules && isDeepSleepEnabled())
{
String event = F("System#NoSleep=");
event += Settings.deepSleep_wakeTime;
rulesProcessing(event); // TD-er: Process events in the setup() now.
}
if (Settings.UseRules)
{
String event = F("System#Wake");
rulesProcessing(event); // TD-er: Process events in the setup() now.
}
NetworkConnectRelaxed();
setWebserverRunning(true);
#ifdef FEATURE_REPORTING
ReportStatus();
#endif
#ifdef FEATURE_ARDUINO_OTA
ArduinoOTAInit();
#endif
if (node_time.systemTimePresent()) {
node_time.initTime();
}
if (Settings.UseRules)
{
String event = F("System#Boot");
rulesProcessing(event); // TD-er: Process events in the setup() now.
}
writeDefaultCSS();
UseRTOSMultitasking = Settings.UseRTOSMultitasking;
#ifdef USE_RTOS_MULTITASKING
if(UseRTOSMultitasking){
log = F("RTOS : Launching tasks");
addLog(LOG_LEVEL_INFO, log);
xTaskCreatePinnedToCore(RTOS_TaskServers, "RTOS_TaskServers", 16384, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(RTOS_TaskSerial, "RTOS_TaskSerial", 8192, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(RTOS_Task10ps, "RTOS_Task10ps", 8192, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(
RTOS_HandleSchedule, /* Function to implement the task */
"RTOS_HandleSchedule", /* Name of the task */
16384, /* Stack size in words */
NULL, /* Task input parameter */
1, /* Priority of the task */
NULL, /* Task handle. */
1); /* Core where the task should run */
}
#endif
// Start the interval timers at N msec from now.
// Make sure to start them at some time after eachother,
// since they will keep running at the same interval.
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_20MSEC, 5); // timer for periodic actions 50 x per/sec
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_100MSEC, 66); // timer for periodic actions 10 x per/sec
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_1SEC, 777); // timer for periodic actions once per/sec
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_30SEC, 1333); // timer for watchdog once per 30 sec
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_MQTT, 88); // timer for interaction with MQTT
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_STATISTICS, 2222);
void setup() {
ESPEasy_setup();
}
#ifdef USE_RTOS_MULTITASKING
void RTOS_TaskServers( void * parameter )
{
while (true){
delay(100);
web_server.handleClient();
checkUDP();
}
void loop() {
ESPEasy_loop();
}
void RTOS_TaskSerial( void * parameter )
{
while (true){
delay(100);
serial();
}
}
void RTOS_Task10ps( void * parameter )
{
while (true){
delay(100);
run10TimesPerSecond();
}
}
void RTOS_HandleSchedule( void * parameter )
{
while (true){
Scheduler.handle_schedule();
}
}
#endif
void updateLoopStats() {
++loopCounter;
++loopCounter_full;
if (lastLoopStart == 0) {
lastLoopStart = micros();
return;
}
const long usecSince = usecPassedSince(lastLoopStart);
#ifdef USES_TIMING_STATS
miscStats[LOOP_STATS].add(usecSince);
#endif
loop_usec_duration_total += usecSince;
lastLoopStart = micros();
if (usecSince <= 0 || usecSince > 10000000)
return; // No loop should take > 10 sec.
if (shortestLoop > static_cast<unsigned long>(usecSince)) {
shortestLoop = usecSince;
loopCounterMax = 30 * 1000000 / usecSince;
}
if (longestLoop < static_cast<unsigned long>(usecSince))
longestLoop = usecSince;
}
float getCPUload() {
return 100.0f - Scheduler.getIdleTimePct();
}
int getLoopCountPerSec() {
return loopCounterLast / 30;
}
int getUptimeMinutes() {
return wdcounter / 2;
}
/*********************************************************************************************\
* MAIN LOOP
\*********************************************************************************************/
void loop()
{
/*
//FIXME TD-er: No idea what this does.
if(MainLoopCall_ptr)
MainLoopCall_ptr();
*/
dummyString = String(); // Fixme TD-er Make sure this global variable doesn't keep memory allocated.
updateLoopStats();
handle_unprocessedNetworkEvents();
bool firstLoopConnectionsEstablished = NetworkConnected() && firstLoop;
if (firstLoopConnectionsEstablished) {
addLog(LOG_LEVEL_INFO, F("firstLoopConnectionsEstablished"));
firstLoop = false;
timerAwakeFromDeepSleep = millis(); // Allow to run for "awake" number of seconds, now we have wifi.
// schedule_all_task_device_timers(); // Disabled for now, since we are now using queues for controllers.
if (Settings.UseRules && isDeepSleepEnabled())
{
String event = F("System#NoSleep=");
event += Settings.deepSleep_wakeTime;
eventQueue.addMove(std::move(event));
}
RTC.bootFailedCount = 0;
saveToRTC();
sendSysInfoUDP(1);
}
// Work around for nodes that do not have WiFi connection for a long time and may reboot after N unsuccessful connect attempts
if (getUptimeMinutes() > 2) {
// Apparently the uptime is already a few minutes. Let's consider it a successful boot.
RTC.bootFailedCount = 0;
saveToRTC();
}
// Deep sleep mode, just run all tasks one (more) time and go back to sleep as fast as possible
if ((firstLoopConnectionsEstablished || readyForSleep()) && isDeepSleepEnabled())
{
#ifdef USES_MQTT
runPeriodicalMQTT();
#endif //USES_MQTT
// Now run all frequent tasks
run50TimesPerSecond();
run10TimesPerSecond();
runEach30Seconds();
runOncePerSecond();
}
//normal mode, run each task when its time
else
{
if (!UseRTOSMultitasking) {
// On ESP32 the schedule is executed on the 2nd core.
Scheduler.handle_schedule();
}
}
backgroundtasks();
if (readyForSleep()){
prepare_deepSleep(Settings.Delay);
//deepsleep will never return, its a special kind of reboot
}
}
void flushAndDisconnectAllClients() {
if (anyControllerEnabled()) {
#ifdef USES_MQTT
bool mqttControllerEnabled = validControllerIndex(firstEnabledMQTT_ControllerIndex());
#endif //USES_MQTT
unsigned long timer = millis() + 1000;
while (!timeOutReached(timer)) {
// call to all controllers (delay queue) to flush all data.
CPluginCall(CPlugin::Function::CPLUGIN_FLUSH, 0);
#ifdef USES_MQTT
if (mqttControllerEnabled && MQTTclient.connected()) {
MQTTclient.loop();
}
#endif //USES_MQTT
}
#ifdef USES_MQTT
if (mqttControllerEnabled && MQTTclient.connected()) {
MQTTclient.disconnect();
updateMQTTclient_connected();
}
#endif //USES_MQTT
saveToRTC();
delay(100); // Flush anything in the network buffers.
}
process_serialWriteBuffer();
}
/*********************************************************************************************\
* run background tasks
\*********************************************************************************************/
bool runningBackgroundTasks=false;
void backgroundtasks()
{
//checkRAM(F("backgroundtasks"));
//always start with a yield
delay(0);
/*
// Remove this watchdog feed for now.
// See https://github.com/letscontrolit/ESPEasy/issues/1722#issuecomment-419659193
#ifdef ESP32
// Have to find a similar function to call ESP32's esp_task_wdt_feed();
#else
ESP.wdtFeed();
#endif
*/
//prevent recursion!
if (runningBackgroundTasks)
{
return;
}
START_TIMER
const bool networkConnected = NetworkConnected();
runningBackgroundTasks=true;
/*
// Not needed anymore, see: https://arduino-esp8266.readthedocs.io/en/latest/faq/readme.html#how-to-clear-tcp-pcbs-in-time-wait-state
if (networkConnected) {
#if defined(ESP8266)
tcpCleanup();
#endif
}
*/
process_serialWriteBuffer();
if(!UseRTOSMultitasking){
serial();
if (webserverRunning) {
web_server.handleClient();
}
if (networkConnected) {
checkUDP();
}
}
#ifdef FEATURE_DNS_SERVER
// process DNS, only used if the ESP has no valid WiFi config
if (dnsServerActive) {
dnsServer.processNextRequest();
}
#endif
#ifdef FEATURE_ARDUINO_OTA
if(Settings.ArduinoOTAEnable && networkConnected)
ArduinoOTA.handle();
//once OTA is triggered, only handle that and dont do other stuff. (otherwise it fails)
while (ArduinoOTAtriggered)
{
delay(0);
if (NetworkConnected()) {
ArduinoOTA.handle();
}
}
#endif
#ifdef FEATURE_MDNS
// Allow MDNS processing
if (networkConnected) {
#ifdef ESP8266
// ESP32 does not have an update() function
MDNS.update();
#endif
}
#endif
delay(0);
statusLED(false);
runningBackgroundTasks=false;
STOP_TIMER(BACKGROUND_TASKS);
}
+3 -10
View File
@@ -7,16 +7,9 @@
// This is only needed until the classes that need these can include the appropriate .h files to have these forward declared.
void backgroundtasks();
void flushAndDisconnectAllClients();
float getCPUload();
int getLoopCountPerSec();
int getUptimeMinutes();
void PluginInit(void);
void CPluginInit(void);
void NPluginInit(void);
-3
View File
@@ -1,3 +0,0 @@
// Some externally needed functions
taskIndex_t findTaskIndexByName(const String& deviceName);
byte findDeviceValueIndexByName(const String& valueName, taskIndex_t taskIndex) ;
+2
View File
@@ -3,7 +3,9 @@
# include "src/Globals/Nodes.h"
# include "src/DataStructs/C013_p2p_dataStructs.h"
# include "src/ESPEasyCore/ESPEasyRules.h"
# include "src/Helpers/Misc.h"
# include "src/Helpers/Network.h"
// #######################################################################################################
// ########################### Controller Plugin 013: ESPEasy P2P network ################################
+4
View File
@@ -1,8 +1,12 @@
#include "src/Helpers/_CPlugin_Helper.h"
#ifdef USES_C014
#include "src/Commands/InternalCommands.h"
#include "src/Globals/Device.h"
#include "src/Globals/MQTT.h"
#include "src/Globals/Plugins.h"
#include "src/Globals/Statistics.h"
#include "src/Helpers/PeriodicalActions.h"
#include "_Plugin_Helper.h"
//#######################################################################################################
+1 -1
View File
@@ -3,7 +3,7 @@
# include "src/Globals/CPlugins.h"
# include "src/Commands/Common.h"
# include "src/ESPEasyCore/ESPEasy_backgroundtasks.h"
// #######################################################################################################
// ########################### Controller Plugin 015: Blynk #############################################
+9
View File
@@ -12,7 +12,16 @@
#define NPLUGIN_001_TIMEOUT 5000
#include "src/DataStructs/NotificationSettingsStruct.h"
#include "src/ESPEasyCore/ESPEasy_Log.h"
#include "src/ESPEasyCore/ESPEasy_backgroundtasks.h"
#include "src/Globals/NPlugins.h"
#include "src/Globals/Settings.h"
#include "src/Helpers/ESPEasy_Storage.h"
#include "src/Helpers/ESPEasy_time_calc.h"
#include "src/Helpers/Networking.h"
#include "src/Helpers/StringParser.h"
#include "src/Helpers/_CPlugin_Helper.h" // safeReadStringUntil
// The message body is included in event->String1
+2
View File
@@ -12,6 +12,8 @@
#include "src/Helpers/Audio.h"
#include "src/DataStructs/NotificationSettingsStruct.h"
#include "src/Globals/NPlugins.h"
#include "src/Helpers/ESPEasy_Storage.h"
boolean NPlugin_002(NPlugin::Function function, struct EventStruct *event, String& string)
{
+3
View File
@@ -1,6 +1,9 @@
#include "_Plugin_Helper.h"
#ifdef USES_P002
#include "src/Helpers/Hardware.h"
// #######################################################################################################
// #################################### Plugin 002: Analog ###############################################
// #######################################################################################################
+1
View File
@@ -4,6 +4,7 @@
#include "src/DataStructs/PinMode.h"
#include "src/Commands/GPIO.h"
#include "src/ESPEasyCore/ESPEasyGPIO.h"
// #######################################################################################################
// #################################### Plugin 009: MCP23017 input #######################################
+1 -1
View File
@@ -7,7 +7,7 @@
// #######################################################################################################
# include "AS_BH1750.h"
# include <AS_BH1750.h>
# define PLUGIN_010
# define PLUGIN_ID_010 10
+3
View File
@@ -1,6 +1,9 @@
#include "_Plugin_Helper.h"
#ifdef USES_P011
#include "ESPEasy-Globals.h" // For dummyString
// #######################################################################################################
// #################################### Plugin 011: Pro Mini Extender ####################################
// #######################################################################################################
+2 -120
View File
@@ -213,7 +213,7 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
if (tmpString.length())
{
String newString = P012_parseTemplate(tmpString, P012_data->Plugin_012_cols);
String newString = P012_data->P012_parseTemplate(tmpString, P012_data->Plugin_012_cols);
P012_data->lcdWrite(newString, 0, x);
}
}
@@ -251,7 +251,7 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
int colPos = event->Par2 - 1;
int rowPos = event->Par1 - 1;
String text = parseStringKeepCase(string, 4);
text = P012_parseTemplate(text, P012_data->Plugin_012_cols);
text = P012_data->P012_parseTemplate(text, P012_data->Plugin_012_cols);
P012_data->lcdWrite(text, colPos, rowPos);
}
@@ -262,124 +262,6 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
return success;
}
// Perform some specific changes for LCD display
// https://www.letscontrolit.com/forum/viewtopic.php?t=2368
String P012_parseTemplate(String& tmpString, byte lineSize) {
String result = parseTemplate_padded(tmpString, lineSize);
const char degree[3] = { 0xc2, 0xb0, 0 }; // Unicode degree symbol
const char degree_lcd[2] = { 0xdf, 0 }; // P012_LCD degree symbol
result.replace(degree, degree_lcd);
char unicodePrefix = 0xc4;
# ifdef USES_P012_POLISH_CHARS
if (result.indexOf(unicodePrefix) != -1) {
const char znak_a_uni[3] = { 0xc4, 0x85, 0 }; // Unicode znak a
const char znak_a_lcd[2] = { 0x05, 0 }; // P012_LCD znak a
result.replace(znak_a_uni, znak_a_lcd);
const char znak_A_uni[3] = { 0xc4, 0x84, 0 }; // Unicode znak A
result.replace(znak_A_uni, znak_a_lcd);
const char znak_c_uni[3] = { 0xc4, 0x87, 0 }; // Unicode znak c
const char znak_c_lcd[2] = { 0x03, 0 }; // P012_LCD znak c
result.replace(znak_c_uni, znak_c_lcd);
const char znak_C_uni[3] = { 0xc4, 0x86, 0 }; // Unicode znak C
result.replace(znak_C_uni, znak_c_lcd);
const char znak_e_uni[3] = { 0xc4, 0x99, 0 }; // Unicode znak e
const char znak_e_lcd[2] = { 0x02, 0 }; // P012_LCD znak e
result.replace(znak_e_uni, znak_e_lcd);
const char znak_E_uni[3] = { 0xc4, 0x98, 0 }; // Unicode znak E
result.replace(znak_E_uni, znak_e_lcd);
}
unicodePrefix = 0xc5;
if (result.indexOf(unicodePrefix) != -1) {
const char znak_l_uni[3] = { 0xc5, 0x82, 0 }; // Unicode znak l
const char znak_l_lcd[2] = { 0x01, 0 }; // P012_LCD znak l
result.replace(znak_l_uni, znak_l_lcd);
const char znak_L_uni[3] = { 0xc5, 0x81, 0 }; // Unicode znak L
result.replace(znak_L_uni, znak_l_lcd);
const char znak_n_uni[3] = { 0xc5, 0x84, 0 }; // Unicode znak n
const char znak_n_lcd[2] = { 0x04, 0 }; // P012_LCD znak n
result.replace(znak_n_uni, znak_n_lcd);
const char znak_N_uni[3] = { 0xc5, 0x83, 0 }; // Unicode znak N
result.replace(znak_N_uni, znak_n_lcd);
const char znak_s_uni[3] = { 0xc5, 0x9b, 0 }; // Unicode znak s
const char znak_s_lcd[2] = { 0x06, 0 }; // P012_LCD znak s
result.replace(znak_s_uni, znak_s_lcd);
const char znak_S_uni[3] = { 0xc5, 0x9a, 0 }; // Unicode znak S
result.replace(znak_S_uni, znak_s_lcd);
const char znak_z1_uni[3] = { 0xc5, 0xba, 0 }; // Unicode znak z z kreska
const char znak_z1_lcd[2] = { 0x07, 0 }; // P012_LCD znak z z kropka
result.replace(znak_z1_uni, znak_z1_lcd);
const char znak_Z1_uni[3] = { 0xc5, 0xb9, 0 }; // Unicode znak Z z kreska
result.replace(znak_Z1_uni, znak_z1_lcd);
const char znak_z2_uni[3] = { 0xc5, 0xbc, 0 }; // Unicode znak z z kropka
const char znak_z2_lcd[2] = { 0x07, 0 }; // P012_LCD znak z z kropka
result.replace(znak_z2_uni, znak_z2_lcd);
const char znak_Z2_uni[3] = { 0xc5, 0xbb, 0 }; // Unicode znak Z z kropka
result.replace(znak_Z2_uni, znak_z2_lcd);
}
unicodePrefix = 0xc3;
if (result.indexOf(unicodePrefix) != -1) {
const char znak_o_uni[3] = { 0xc3, 0xB3, 0 }; // Unicode znak o
const char znak_o_lcd[2] = { 0x08, 0 }; // P012_LCD znak o
result.replace(znak_o_uni, znak_o_lcd);
const char znak_O_uni[3] = { 0xc3, 0x93, 0 }; // Unicode znak O
result.replace(znak_O_uni, znak_o_lcd);
}
# endif // USES_P012_POLISH_CHARS
unicodePrefix = 0xc3;
if (result.indexOf(unicodePrefix) != -1) {
// See: https://github.com/letscontrolit/ESPEasy/issues/2081
const char umlautAE_uni[3] = { 0xc3, 0x84, 0 }; // Unicode Umlaute AE
const char umlautAE_lcd[2] = { 0xe1, 0 }; // P012_LCD Umlaute
result.replace(umlautAE_uni, umlautAE_lcd);
const char umlaut_ae_uni[3] = { 0xc3, 0xa4, 0 }; // Unicode Umlaute ae
result.replace(umlaut_ae_uni, umlautAE_lcd);
const char umlautOE_uni[3] = { 0xc3, 0x96, 0 }; // Unicode Umlaute OE
const char umlautOE_lcd[2] = { 0xef, 0 }; // P012_LCD Umlaute
result.replace(umlautOE_uni, umlautOE_lcd);
const char umlaut_oe_uni[3] = { 0xc3, 0xb6, 0 }; // Unicode Umlaute oe
result.replace(umlaut_oe_uni, umlautOE_lcd);
const char umlautUE_uni[3] = { 0xc3, 0x9c, 0 }; // Unicode Umlaute UE
const char umlautUE_lcd[2] = { 0xf5, 0 }; // P012_LCD Umlaute
result.replace(umlautUE_uni, umlautUE_lcd);
const char umlaut_ue_uni[3] = { 0xc3, 0xbc, 0 }; // Unicode Umlaute ue
result.replace(umlaut_ue_uni, umlautUE_lcd);
const char umlaut_sz_uni[3] = { 0xc3, 0x9f, 0 }; // Unicode Umlaute sz
const char umlaut_sz_lcd[2] = { 0xe2, 0 }; // P012_LCD Umlaute
result.replace(umlaut_sz_uni, umlaut_sz_lcd);
}
return result;
}
#endif // USES_P012
+2
View File
@@ -25,6 +25,8 @@
#include "src/PluginStructs/P016_data_struct.h"
#include "src/ESPEasyCore/Serial.h"
#ifdef P016_P035_Extended_AC
#include <IRac.h>
#endif
+3
View File
@@ -1,5 +1,8 @@
#include "_Plugin_Helper.h"
#ifdef USES_P018
#include "src/Helpers/Hardware.h"
//#######################################################################################################
//#################################### Plugin 018: GP2Y10 ###############################################
//#######################################################################################################
+1
View File
@@ -3,6 +3,7 @@
#include "src/DataStructs/PinMode.h"
#include "src/Commands/GPIO.h"
#include "src/ESPEasyCore/ESPEasyGPIO.h"
// #######################################################################################################
// #################################### Plugin 019: PCF8574 ##############################################
+1
View File
@@ -5,6 +5,7 @@
//#######################################################################################################
#include "src/Helpers/Rules_calculate.h"
#include "src/WebServer/WebServer.h"
#define PLUGIN_021
#define PLUGIN_ID_021 21
+3
View File
@@ -5,6 +5,9 @@
#include "src/Helpers/PortStatus.h"
#include "src/PluginStructs/P022_data_struct.h"
#include "ESPEasy-Globals.h" // For dummystring
// #######################################################################################################
// #################################### Plugin 022: PCA9685 ##############################################
// #######################################################################################################
+1
View File
@@ -19,6 +19,7 @@
#define PLUGIN_VALUENAME2_056 "PM10" // Dust <10µm in µg/m³
#include <jkSDS011.h>
#include "ESPEasy-Globals.h"
CjkSDS011 *Plugin_056_SDS = NULL;
+1
View File
@@ -14,6 +14,7 @@
#include <ESPeasySerial.h>
#include "src/ESPEasyCore/Serial.h"
#define PLUGIN_071
#define PLUGIN_ID_071 71
+1
View File
@@ -58,6 +58,7 @@
#include <ESPeasySerial.h>
#include "src/Helpers/Modbus_RTU.h"
#include "src/DataStructs/ESPEasy_packed_raw_data.h"
struct P085_data_struct : public PluginTaskData_base {
P085_data_struct() {}
+2
View File
@@ -20,6 +20,8 @@ extern "C"
#include <lwip/netif.h>
}
#include "src/ESPEasyCore/ESPEasyNetwork.h"
#define PLUGIN_089
#define PLUGIN_ID_089 89
+2
View File
@@ -61,6 +61,8 @@
#include "src/PluginStructs/P092_data_struct.h"
#include "src/ESPEasyCore/ESPEasyNetwork.h"
#define PLUGIN_092
#define PLUGIN_ID_092 92
+2
View File
@@ -11,6 +11,8 @@
# include <ESPeasySerial.h>
# include <PZEM004Tv30.h>
#include "src/DataStructs/ESPEasy_packed_raw_data.h"
# define PLUGIN_102
# define PLUGIN_ID_102 102
+1
View File
@@ -70,6 +70,7 @@ DF - Below doesn't look right; needs a RS485 to TTL(3.3v) level converter (see h
#include <ESPeasySerial.h>
#include "src/Helpers/Modbus_RTU.h"
#include "src/DataStructs/ESPEasy_packed_raw_data.h"
struct P108_data_struct : public PluginTaskData_base {
P108_data_struct() {}
+484
View File
@@ -0,0 +1,484 @@
#include "_Plugin_Helper.h"
#ifdef USES_P112
// #######################################################################################################
// #################### Plugin 112 I2C AS7265X Triad Spectroscopy Sensor and White, IR and UV LED ########
// #######################################################################################################
//
// Triad Spectroscopy Sensor and White, IR and UV LED
// like this one: https://www.sparkfun.com/products/15050
// based on this library: https://github.com/sparkfun/SparkFun_AS7265x_Arduino_Library
// this code is based on 29 Mar 2019-03-29 version of the above library
//
// 2021-03-29 heinemannj: Initial commit
//
#include "src/PluginStructs/P112_data_struct.h"
#define PLUGIN_112
#define PLUGIN_ID_112 112
#define PLUGIN_NAME_112 "Color - AS7265X [DEVELOPMENT]"
#define PLUGIN_VALUENAME1_112 "TempMaster"
#define PLUGIN_VALUENAME2_112 "TempAverage"
#define PLUGIN_VALUENAME3_112 "State"
#define AS7265X_ADDR 0x49
boolean Plugin_112(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_112;
Device[deviceCount].Type = DEVICE_TYPE_I2C;
Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_TRIPLE;
Device[deviceCount].Ports = 0;
Device[deviceCount].ValueCount = 3;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = false;
Device[deviceCount].DecimalsOnly = true;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].GlobalSyncOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].OutputDataType = Output_Data_type_t::All;
break;
}
case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_112);
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_112));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_112));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_112));
break;
}
case PLUGIN_WEBFORM_SHOW_I2C_PARAMS:
{
int optionValues[1] = { AS7265X_ADDR };
addFormSelectorI2C(F("i2c_addr"), 1, optionValues, AS7265X_ADDR);
break;
}
case PLUGIN_SET_DEFAULTS:
{
PCONFIG_LONG(0) = AS7265X_GAIN_37X; // Set Gain (AS7265X_GAIN_37X) => This is 3.7x
PCONFIG_LONG(1) = 254; // Set Integration Cycles => 254*2.8ms = 711ms per Reading
PCONFIG(0) = 0; // Blue Status LED On
PCONFIG(1) = AS7265X_INDICATOR_CURRENT_LIMIT_8MA; // Blue Status LED Current Limit
PCONFIG(2) = AS7265X_LED_CURRENT_LIMIT_12_5MA; // White LED Current Limit
PCONFIG(3) = AS7265X_LED_CURRENT_LIMIT_12_5MA; // IR LED Current Limit
PCONFIG(4) = AS7265X_LED_CURRENT_LIMIT_12_5MA; // UV LED Current Limit
PCONFIG(5) = 0; // During Measurement turn White, IR and UV LEDs On
PCONFIG(6) = 1; // Use Calibrated Readings
success = true;
break;
}
case PLUGIN_WEBFORM_LOAD:
{
byte choiceMode = PCONFIG_LONG(0);
{
// sensor.setGain(AS7265X_GAIN_1X); //Default
// sensor.setGain(AS7265X_GAIN_37X); //This is 3.7x
// sensor.setGain(AS7265X_GAIN_16X);
// sensor.setGain(AS7265X_GAIN_64X);
String optionsMode[4];
optionsMode[0] = F("1x");
optionsMode[1] = F("3.7x (default)");
optionsMode[2] = F("16x");
optionsMode[3] = F("64x");
int optionValuesMode[4];
optionValuesMode[0] = AS7265X_GAIN_1X;
optionValuesMode[1] = AS7265X_GAIN_37X;
optionValuesMode[2] = AS7265X_GAIN_16X;
optionValuesMode[3] = AS7265X_GAIN_64X;
addFormSelector(F("Gain"), F("p112_Gain"), 4, optionsMode, optionValuesMode, choiceMode);
}
byte choiceMode2 = PCONFIG_LONG(1);
{
// Integration cycles from 0 (2.78ms) to 255 (711ms)
// sensor.setIntegrationCycles(49); //Default: 50*2.8ms = 140ms per reading
// sensor.setIntegrationCycles(1); //2*2.8ms = 5.6ms per reading
String optionsMode2[6];
optionsMode2[0] = F("2.8 ms");
optionsMode2[1] = F("28 ms");
optionsMode2[2] = F("56 ms");
optionsMode2[3] = F("140 ms");
optionsMode2[4] = F("280 ms");
optionsMode2[5] = F("711 ms (default)");
int optionValuesMode2[6];
optionValuesMode2[0] = 0;
optionValuesMode2[1] = 9;
optionValuesMode2[2] = 19;
optionValuesMode2[3] = 49;
optionValuesMode2[4] = 99;
optionValuesMode2[5] = 254;
addFormSelector(F("Integration Time"), F("p112_IntegrationTime"), 6, optionsMode2, optionValuesMode2, choiceMode2);
}
addFormNote(F("Raw Readings shall not reach the upper limit of 65535 (Sensor Saturation)."));
addFormSubHeader(F("LED settings"));
addFormCheckBox(F("Blue"), F("p112_BlueStatusLED"), PCONFIG(0));
addHtml(F(" Status LED On"));
byte choiceMode3 = PCONFIG(1);
{
// sensor.setIndicatorCurrent(AS7265X_INDICATOR_CURRENT_LIMIT_1MA);
// sensor.setIndicatorCurrent(AS7265X_INDICATOR_CURRENT_LIMIT_2MA);
// sensor.setIndicatorCurrent(AS7265X_INDICATOR_CURRENT_LIMIT_4MA);
// sensor.setIndicatorCurrent(AS7265X_INDICATOR_CURRENT_LIMIT_8MA); //Default
String optionsMode3[4];
optionsMode3[0] = F("1 mA");
optionsMode3[1] = F("2 mA");
optionsMode3[2] = F("4 mA");
optionsMode3[3] = F("8 mA (default)");
int optionValuesMode3[4];
optionValuesMode3[0] = AS7265X_INDICATOR_CURRENT_LIMIT_1MA;
optionValuesMode3[1] = AS7265X_INDICATOR_CURRENT_LIMIT_2MA;
optionValuesMode3[2] = AS7265X_INDICATOR_CURRENT_LIMIT_4MA;
optionValuesMode3[3] = AS7265X_INDICATOR_CURRENT_LIMIT_8MA;
addFormSelector(F(""), F("p112_BlueStatusLEDCurrentLimit"), 4, optionsMode3, optionValuesMode3, choiceMode3);
}
addHtml(F(" Current Limit"));
addFormNote(F("Activate Status LEDs only for debugging purpose."));
byte choiceMode4 = PCONFIG(2);
{
// White LED has max forward current of 120mA
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_12_5MA, AS7265x_LED_WHITE); //Default
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_25MA, AS7265x_LED_WHITE); //Allowed
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_50MA, AS7265x_LED_WHITE); //Allowed
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_100MA, AS7265x_LED_WHITE); //Allowed
String optionsMode4[4];
optionsMode4[0] = F("12.5 mA (default)");
optionsMode4[1] = F("25 mA");
optionsMode4[2] = F("50 mA");
optionsMode4[3] = F("100 mA");
int optionValuesMode4[4];
optionValuesMode4[0] = AS7265X_LED_CURRENT_LIMIT_12_5MA;
optionValuesMode4[1] = AS7265X_LED_CURRENT_LIMIT_25MA;
optionValuesMode4[2] = AS7265X_LED_CURRENT_LIMIT_50MA;
optionValuesMode4[3] = AS7265X_LED_CURRENT_LIMIT_100MA;
addFormSelector(F("White"), F("p112_WhiteLEDCurrentLimit"), 4, optionsMode4, optionValuesMode4, choiceMode4);
}
addHtml(F(" Current Limit"));
byte choiceMode5 = PCONFIG(3);
{
// IR LED has max forward current of 65mA
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_12_5MA, AS7265x_LED_IR); //Default
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_25MA, AS7265x_LED_IR); //Allowed
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_50MA, AS7265x_LED_IR); //Allowed
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_100MA, AS7265x_LED_IR-bad); //Not allowed
String optionsMode5[3];
optionsMode5[0] = F("12.5 mA (default)");
optionsMode5[1] = F("25 mA");
optionsMode5[2] = F("50 mA");
int optionValuesMode5[3];
optionValuesMode5[0] = AS7265X_LED_CURRENT_LIMIT_12_5MA;
optionValuesMode5[1] = AS7265X_LED_CURRENT_LIMIT_25MA;
optionValuesMode5[2] = AS7265X_LED_CURRENT_LIMIT_50MA;
addFormSelector(F("IR"), F("p112_IRLEDCurrentLimit"), 3, optionsMode5, optionValuesMode5, choiceMode5);
}
byte choiceMode6 = PCONFIG(4);
{
// UV LED has max forward current of 30mA so do not set the drive current higher
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_12_5MA, AS7265x_LED_UV); //Default
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_25MA, AS7265x_LED_UV-bad); //Not allowed
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_50MA, AS7265x_LED_UV-bad); //Not allowed
// sensor.setBulbCurrent(AS7265X_LED_CURRENT_LIMIT_100MA, AS7265x_LED_UV-bad); //Not allowed
String optionsMode6[1];
optionsMode6[0] = F("12.5 mA (default)");
int optionValuesMode6[1];
optionValuesMode6[0] = AS7265X_LED_CURRENT_LIMIT_12_5MA;
addFormSelector(F("UV"), F("p112_UVLEDCurrentLimit"), 1, optionsMode6, optionValuesMode6, choiceMode6);
}
addFormNote(F("Control Gain and Integration Time after any change to avoid Sensor Saturation!"));
addFormSubHeader(F("Measurement settings"));
addFormCheckBox(F("LEDs"), F("p112_MeasurementWithLEDsOn"), PCONFIG(5));
addHtml(F(" White, IR and UV On"));
addFormCheckBox(F("Calibrated Readings"), F("p112_CalibratedReadings"), PCONFIG(6));
addFormNote(F("Unchecked (Raw Readings): Use only for the adjustment of Device and LED settings"));
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
PCONFIG_LONG(0) = getFormItemInt(F("p112_Gain"));
PCONFIG_LONG(1) = getFormItemInt(F("p112_IntegrationTime"));
PCONFIG(0) = isFormItemChecked(F("p112_BlueStatusLED"));
PCONFIG(1) = getFormItemInt(F("p112_BlueStatusLEDCurrentLimit"));
PCONFIG(2) = getFormItemInt(F("p112_WhiteLEDCurrentLimit"));
PCONFIG(3) = getFormItemInt(F("p112_IRLEDCurrentLimit"));
PCONFIG(4) = getFormItemInt(F("p112_UVLEDCurrentLimit"));
PCONFIG(5) = isFormItemChecked(F("p112_MeasurementWithLEDsOn"));
PCONFIG(6) = isFormItemChecked(F("p112_CalibratedReadings"));
success = true;
break;
}
case PLUGIN_INIT:
{
initPluginTaskData(event->TaskIndex, new (std::nothrow) P112_data_struct());
P112_data_struct *P112_data =
static_cast<P112_data_struct *>(getPluginTaskData(event->TaskIndex));
if (nullptr != P112_data) {
P112_data->initialized = false; // Force re-init just in case the address changed.
if (P112_data->begin()) {
addLog(LOG_LEVEL_INFO, F("AS7265X: Found sensor"));
success = P112_data->initialized;
P112_data->sensor.setGain(PCONFIG_LONG(0));
P112_data->sensor.setIntegrationCycles(PCONFIG_LONG(1));
if (PCONFIG(0)) // Blue Status LED
{
P112_data->sensor.enableIndicator();
} else {
P112_data->sensor.disableIndicator();
}
P112_data->sensor.setIndicatorCurrent(PCONFIG(1));
P112_data->sensor.disableBulb(AS7265x_LED_WHITE);
P112_data->sensor.disableBulb(AS7265x_LED_IR);
P112_data->sensor.disableBulb(AS7265x_LED_UV);
P112_data->sensor.setBulbCurrent(PCONFIG(2), AS7265x_LED_WHITE);
P112_data->sensor.setBulbCurrent(PCONFIG(3), AS7265x_LED_IR);
P112_data->sensor.setBulbCurrent(PCONFIG(4), AS7265x_LED_UV);
String log = F("AS7265X: AMS Device Type: 0x");
log += P112_data->sensor.getDeviceType();
addLog(LOG_LEVEL_INFO, log);
log = F("AS7265X: AMS Hardware Version: 0x");
log += P112_data->sensor.getHardwareVersion();
addLog(LOG_LEVEL_INFO, log);
log = F("AS7265X: AMS Major Firmware Version: 0x");
log += P112_data->sensor.getMajorFirmwareVersion();
addLog(LOG_LEVEL_INFO, log);
log = F("AS7265X: AMS Patch Firmware Version: 0x");
log += P112_data->sensor.getPatchFirmwareVersion();
addLog(LOG_LEVEL_INFO, log)
log = F("AS7265X: AMS Build Firmware Version: 0x");
log += P112_data->sensor.getBuildFirmwareVersion();
addLog(LOG_LEVEL_INFO, log)
success = true;
} else {
addLog(LOG_LEVEL_INFO, F("AS7265X: No sensor found"));
success = false;
}
}
break;
}
case PLUGIN_TEN_PER_SECOND:
{
P112_data_struct *P112_data =
static_cast<P112_data_struct *>(getPluginTaskData(event->TaskIndex));
if (nullptr != P112_data) {
if ((P112_data->sensor.dataAvailable()) or (P112_data->MeasurementStatus >= 1)) {
P112_data->MeasurementStatus = P112_data->MeasurementStatus + 1;
String RuleEvent;
RuleEvent = getTaskDeviceName(event->TaskIndex);
RuleEvent += '#';
switch (P112_data->MeasurementStatus) {
case 1:
P112_data->sensor.disableBulb(AS7265x_LED_WHITE);
P112_data->sensor.disableBulb(AS7265x_LED_IR);
P112_data->sensor.disableBulb(AS7265x_LED_UV);
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("410=")) + P112_data->sensor.getCalibratedA());
} else {
eventQueue.add(RuleEvent + String(F("410=")) + P112_data->sensor.getA());
}
break;
case 2:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("435=")) + P112_data->sensor.getCalibratedB());
} else {
eventQueue.add(RuleEvent + String(F("435=")) + P112_data->sensor.getB());
}
break;
case 3:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("460=")) + P112_data->sensor.getCalibratedC());
} else {
eventQueue.add(RuleEvent + String(F("460=")) + P112_data->sensor.getC());
}
break;
case 4:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("485=")) + P112_data->sensor.getCalibratedD());
} else {
eventQueue.add(RuleEvent + String(F("485=")) + P112_data->sensor.getD());
}
break;
case 5:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("510=")) + P112_data->sensor.getCalibratedE());
} else {
eventQueue.add(RuleEvent + String(F("510=")) + P112_data->sensor.getE());
}
break;
case 6:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("535=")) + P112_data->sensor.getCalibratedF());
} else {
eventQueue.add(RuleEvent + String(F("535=")) + P112_data->sensor.getF());
}
break;
case 7:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("560=")) + P112_data->sensor.getCalibratedG());
} else {
eventQueue.add(RuleEvent + String(F("560=")) + P112_data->sensor.getG());
}
break;
case 8:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("585=")) + P112_data->sensor.getCalibratedH());
} else {
eventQueue.add(RuleEvent + String(F("585=")) + P112_data->sensor.getH());
}
break;
case 9:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("610=")) + P112_data->sensor.getCalibratedR());
} else {
eventQueue.add(RuleEvent + String(F("610=")) + P112_data->sensor.getR());
}
break;
case 10:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("645=")) + P112_data->sensor.getCalibratedI());
} else {
eventQueue.add(RuleEvent + String(F("645=")) + P112_data->sensor.getI());
}
break;
case 11:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("680=")) + P112_data->sensor.getCalibratedS());
} else {
eventQueue.add(RuleEvent + String(F("680=")) + P112_data->sensor.getS());
}
break;
case 12:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("705=")) + P112_data->sensor.getCalibratedJ());
} else {
eventQueue.add(RuleEvent + String(F("705=")) + P112_data->sensor.getJ());
}
break;
case 13:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("730=")) + P112_data->sensor.getCalibratedT());
} else {
eventQueue.add(RuleEvent + String(F("730=")) + P112_data->sensor.getT());
}
break;
case 14:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("760=")) + P112_data->sensor.getCalibratedU());
} else {
eventQueue.add(RuleEvent + String(F("760=")) + P112_data->sensor.getU());
}
break;
case 15:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("810=")) + P112_data->sensor.getCalibratedV());
} else {
eventQueue.add(RuleEvent + String(F("810=")) + P112_data->sensor.getV());
}
break;
case 16:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("860=")) + P112_data->sensor.getCalibratedW());
} else {
eventQueue.add(RuleEvent + String(F("860=")) + P112_data->sensor.getW());
}
break;
case 17:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("900=")) + P112_data->sensor.getCalibratedK());
} else {
eventQueue.add(RuleEvent + String(F("900=")) + P112_data->sensor.getK());
}
break;
case 18:
if (PCONFIG(6)) {
eventQueue.add(RuleEvent + String(F("940=")) + P112_data->sensor.getCalibratedL());
} else {
eventQueue.add(RuleEvent + String(F("940=")) + P112_data->sensor.getL());
}
P112_data->MeasurementStatus = 0;
UserVar[event->BaseVarIndex + 2] = 0;
if (PCONFIG(0)) // Blue Status LED
{
P112_data->sensor.enableIndicator();
}
break;
}
}
}
break;
}
case PLUGIN_READ:
{
P112_data_struct *P112_data =
static_cast<P112_data_struct *>(getPluginTaskData(event->TaskIndex));
if (P112_data->MeasurementStatus == 0) {
if (P112_data->begin()) {
UserVar[event->BaseVarIndex + 2] = 1;
P112_data->sensor.disableIndicator(); // Blue Status LEDs Off
if (PCONFIG(5)) // Measurement With LEDs On
{
P112_data->sensor.enableBulb(AS7265x_LED_WHITE);
P112_data->sensor.enableBulb(AS7265x_LED_IR);
P112_data->sensor.enableBulb(AS7265x_LED_UV);
}
// There are four measurement modes - the datasheet describes it best
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// sensor.setMeasurementMode(AS7265X_MEASUREMENT_MODE_4CHAN); //Channels STUV on x51
// sensor.setMeasurementMode(AS7265X_MEASUREMENT_MODE_4CHAN_2); //Channels RTUW on x51
// sensor.setMeasurementMode(AS7265X_MEASUREMENT_MODE_6CHAN_CONTINUOUS); //All 6 channels on all devices
// sensor.setMeasurementMode(AS7265X_MEASUREMENT_MODE_6CHAN_ONE_SHOT); //Default: All 6 channels, all devices, just once
//
P112_data->sensor.setMeasurementMode(AS7265X_MEASUREMENT_MODE_6CHAN_ONE_SHOT);
UserVar[event->BaseVarIndex + 0] = P112_data->sensor.getTemperature();
UserVar[event->BaseVarIndex + 1] = P112_data->sensor.getTemperatureAverage();
}
}
success = true;
break;
}
}
return success;
}
#endif // USES_P112
+7
View File
@@ -18,6 +18,8 @@
#include "src/Globals/Device.h"
#include "src/Globals/ESPEasy_Scheduler.h"
#include "src/Globals/ESPEasy_time.h"
#include "src/Globals/EventQueue.h"
#include "src/Globals/ExtraTaskSettings.h"
#include "src/Globals/GlobalMapPortStatus.h"
#include "src/Globals/I2Cdev.h"
@@ -26,8 +28,11 @@
#include "src/Globals/Settings.h"
#include "src/Helpers/ESPEasy_math.h"
#include "src/Helpers/ESPEasy_Storage.h"
#include "src/Helpers/ESPEasy_time_calc.h"
#include "src/Helpers/I2C_access.h"
#include "src/Helpers/Misc.h"
#include "src/Helpers/Numerical.h"
#include "src/Helpers/PortStatus.h"
#include "src/Helpers/StringConverter.h"
#include "src/Helpers/StringGenerator_GPIO.h"
@@ -38,6 +43,8 @@
#include "src/WebServer/HTML_wrappers.h"
#include "src/WebServer/Markup.h"
#include "src/WebServer/Markup_Forms.h"
#include "src/WebServer/WebServer.h"
// Defines to make plugins more readable.
+2
View File
@@ -2,6 +2,8 @@
#ifdef USES_NOTIFIER
#include "src/Globals/NPlugins.h"
#include "src/DataStructs/ESPEasy_EventStruct.h"
// ********************************************************************************
+3 -2
View File
@@ -1,15 +1,16 @@
#include "../Commands/Blynk.h"
#include "../../ESPEasy_fdwdecl.h"
#include "../Commands/Common.h"
#include "../DataStructs/ESPEasy_EventStruct.h"
#include "../ESPEasyCore/ESPEasy_backgroundtasks.h"
#include "../ESPEasyCore/ESPEasy_Log.h"
#include "../Globals/Protocol.h"
#include "../Globals/Settings.h"
#include "../Helpers/_CPlugin_Helper.h"
#include "../Helpers/ESPEasy_Storage.h"
#include "../Helpers/ESPEasy_time_calc.h"
#include "../Helpers/_CPlugin_Helper.h"
#include "../../ESPEasy_fdwdecl.h"
#ifdef USES_C012
+6 -3
View File
@@ -7,7 +7,7 @@
#include "../DataStructs/ESPEasy_EventStruct.h"
*/
#include "../../ESPEasy_fdwdecl.h"
#include "../Commands/Common.h"
@@ -15,6 +15,7 @@
#include "../DataTypes/SettingsType.h"
#include "../ESPEasyCore/ESPEasy_backgroundtasks.h"
#include "../ESPEasyCore/ESPEasy_Log.h"
#include "../ESPEasyCore/Serial.h"
@@ -158,8 +159,10 @@ String Command_Debug(struct EventStruct *event, const char *Line)
String Command_logentry(struct EventStruct *event, const char *Line)
{
// FIXME TD-er: Add an extra optional parameter to set log level.
addLog(LOG_LEVEL_INFO, tolerantParseStringKeepCase(Line, 2));
byte level = LOG_LEVEL_INFO;
// An extra optional parameter to set log level.
if (event->Par2 > LOG_LEVEL_NONE && event->Par2 <= LOG_LEVEL_DEBUG_MORE) { level = event->Par2; }
addLog(level, tolerantParseStringKeepCase(Line, 2));
return return_command_success();
}
+452 -380
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -258,7 +258,7 @@ bool executeInternalCommand(command_case_data & data)
case 'l': {
COMMAND_CASE_A( "let", Command_Rules_Let, 2); // Rules.h
COMMAND_CASE_A( "load", Command_Settings_Load, 0); // Settings.h
COMMAND_CASE_A( "logentry", Command_logentry, 1); // Diagnostic.h
COMMAND_CASE_A( "logentry", Command_logentry, -1); // Diagnostic.h
COMMAND_CASE_A( "looptimerset", Command_Loop_Timer_Set, 3); // Timers.h
COMMAND_CASE_A("looptimerset_ms", Command_Loop_Timer_Set_ms, 3); // Timers.h
COMMAND_CASE_A( "longpulse", Command_GPIO_LongPulse, 3); // GPIO.h
@@ -396,6 +396,7 @@ bool executeInternalCommand(command_case_data & data)
#endif
if (data.cmd_lc[1] == 'i') {
COMMAND_CASE_R( "wifiallowap", Command_Wifi_AllowAP, 0); // WiFi.h
COMMAND_CASE_R( "wifiapmode", Command_Wifi_APMode, 0); // WiFi.h
COMMAND_CASE_A( "wificonnect", Command_Wifi_Connect, 0); // WiFi.h
COMMAND_CASE_A("wifidisconnect", Command_Wifi_Disconnect, 0); // WiFi.h
+1 -2
View File
@@ -14,8 +14,7 @@
#include "../Helpers/Misc.h"
#include "../Helpers/Rules_calculate.h"
#include "../Helpers/StringConverter.h"
#include "../../Misc.h"
#include "../Helpers/StringParser.h"
// taskIndex = (event->Par1 - 1); Par1 is here for 1 ... TASKS_MAX
// varNr = event->Par2 - 1;
+6
View File
@@ -118,6 +118,12 @@ String Command_Wifi_Mode(struct EventStruct *event, const char *Line)
return return_command_success();
}
String Command_Wifi_AllowAP(struct EventStruct *event, const char* Line)
{
Settings.DoNotStartAP(false);
return return_command_success();
}
// FIXME: TD-er This is not an erase, but actually storing the current settings
// in the wifi settings of the core library
String Command_WiFi_Erase(struct EventStruct *event, const char *Line)
+1
View File
@@ -15,6 +15,7 @@ String Command_Wifi_Disconnect(struct EventStruct *event, const char* Line);
String Command_Wifi_APMode(struct EventStruct *event, const char* Line);
String Command_Wifi_STAMode(struct EventStruct *event, const char* Line);
String Command_Wifi_Mode(struct EventStruct *event, const char* Line);
String Command_Wifi_AllowAP(struct EventStruct *event, const char* Line);
// FIXME: TD-er This is not an erase, but actually storing the current settings
// in the wifi settings of the core library
@@ -39,7 +39,6 @@ size_t C015_queue_element::getSize() const {
bool C015_queue_element::isDuplicate(const C015_queue_element& other) const {
if ((other.controller_idx != controller_idx) ||
(other.TaskIndex != TaskIndex) ||
(other.sensorType != sensorType) ||
(other.valueCount != valueCount) ||
(other.idx != idx)) {
return false;
+5 -1
View File
@@ -109,7 +109,11 @@
#endif
#ifndef DEFAULT_AP_DONT_FORCE_SETUP
#define DEFAULT_AP_DONT_FORCE_SETUP false // Allow optional usage of Sensor without WIFI avaiable // When set you can use the Sensor in AP-Mode without beeing forced to /setup
#define DEFAULT_AP_DONT_FORCE_SETUP false // Allow optional usage of Sensor without WIFI avaiable // When set you can use the Sensor in AP-Mode without beeing forced to /setup
#endif
#ifndef DEFAULT_DONT_ALLOW_START_AP
#define DEFAULT_DONT_ALLOW_START_AP false // Usually the AP will be started when no WiFi is defined, or the defined one cannot be found. This flag may prevent it.
#endif
// --- Default Controller ------------------------------------------------------------------------------
+2 -2
View File
@@ -1312,10 +1312,10 @@ To create/register a plugin, you have to :
// Plugins
#ifndef USES_P016
#define USES_P016 // IR
// #define USES_P016 // IR
#endif
#ifndef USES_P035
#define USES_P035 // IRTX
// #define USES_P035 // IRTX
#endif
#ifndef USES_P041
#define USES_P041 // NeoClock
@@ -1,4 +1,4 @@
#include "ESPEasy_packed_raw_data.h"
#include "../DataStructs/ESPEasy_packed_raw_data.h"
uint8_t getPackedDataTypeSize(PackedData_enum dtype, float& factor, float& offset) {
+11
View File
@@ -195,6 +195,16 @@ void SettingsStruct_tmpl<N_TASKS>::CombineTaskValues_SingleEvent(taskIndex_t tas
}
}
template<unsigned int N_TASKS>
bool SettingsStruct_tmpl<N_TASKS>::DoNotStartAP() const {
return bitRead(VariousBits1, 17);
}
template<unsigned int N_TASKS>
void SettingsStruct_tmpl<N_TASKS>::DoNotStartAP(bool value) {
bitWrite(VariousBits1, 17, value);
}
template<unsigned int N_TASKS>
void SettingsStruct_tmpl<N_TASKS>::validate() {
if (UDPPort > 65535) { UDPPort = 0; }
@@ -360,6 +370,7 @@ void SettingsStruct_tmpl<N_TASKS>::clearMisc() {
TolerantLastArgParse(DEFAULT_TOLERANT_LAST_ARG_PARSE);
SendToHttp_ack(DEFAULT_SEND_TO_HTTP_ACK);
ApDontForceSetup(DEFAULT_AP_DONT_FORCE_SETUP);
DoNotStartAP(DEFAULT_DONT_ALLOW_START_AP);
}
template<unsigned int N_TASKS>
+2
View File
@@ -115,6 +115,8 @@ class SettingsStruct_tmpl
bool CombineTaskValues_SingleEvent(taskIndex_t taskIndex) const;
void CombineTaskValues_SingleEvent(taskIndex_t taskIndex, bool value);
bool DoNotStartAP() const;
void DoNotStartAP(bool value);
void validate();
+19
View File
@@ -15,6 +15,7 @@
#define ESPEASY_WIFI_SERVICES_INITIALIZED 2
#define WIFI_RECONNECT_WAIT 20000 // in milliSeconds
#define WIFI_PROCESS_EVENTS_TIMEOUT 10000 // in milliSeconds
bool WiFiEventData_t::WiFiConnectAllowed() const {
if (!wifiConnectAttemptNeeded) return false;
@@ -33,6 +34,24 @@ bool WiFiEventData_t::unprocessedWifiEvents() const {
{
return false;
}
if (!processedConnect) {
if (lastConnectMoment.isSet() && lastConnectMoment.timeoutReached(WIFI_PROCESS_EVENTS_TIMEOUT)) {
return false;
}
}
if (!processedGotIP) {
if (lastGetIPmoment.isSet() && lastGetIPmoment.timeoutReached(WIFI_PROCESS_EVENTS_TIMEOUT)) {
return false;
}
}
if (!processedDisconnect) {
if (lastDisconnectMoment.isSet() && lastDisconnectMoment.timeoutReached(WIFI_PROCESS_EVENTS_TIMEOUT)) {
return false;
}
}
if (!processedDHCPTimeout) {
return false;
}
return true;
}
+2 -1
View File
@@ -4,10 +4,11 @@
#include "../Globals/SecuritySettings.h"
#include "../Globals/Statistics.h"
#include "../Helpers/ESPEasy_time_calc.h"
#include "../Helpers/Misc.h"
#include "../Helpers/StringConverter.h"
#include "../Helpers/StringGenerator_WiFi.h"
#include "../../ESPEasy_common.h"
#include "../../ESPEasy_fdwdecl.h"
+1 -1
View File
@@ -1,4 +1,4 @@
#include "Controller.h"
#include "../ESPEasyCore/Controller.h"
#include "../../ESPEasy_common.h"
#include "../../ESPEasy-Globals.h"
+1 -1
View File
@@ -1,5 +1,5 @@
#include "ESPEasyGPIO.h"
#include "../ESPEasyCore/ESPEasyGPIO.h"
/****************************************************************************/
// Central functions for GPIO handling
+3 -2
View File
@@ -1,8 +1,9 @@
#include "ESPEasyRules.h"
#include "../ESPEasyCore/ESPEasyRules.h"
#include "../Commands/InternalCommands.h"
#include "../DataStructs/TimingStats.h"
#include "../DataTypes/EventValueSource.h"
#include "../ESPEasyCore/ESPEasy_backgroundtasks.h"
#include "../ESPEasyCore/Serial.h"
#include "../Globals/Device.h"
#include "../Globals/EventQueue.h"
@@ -21,7 +22,7 @@
#include "../../_Plugin_Helper.h"
#include "../../ESPEasy_fdwdecl.h"
#include <math.h>
+7 -3
View File
@@ -21,7 +21,7 @@
#include "../Helpers/StringConverter.h"
#include "../Helpers/StringGenerator_WiFi.h"
#include "../../ESPEasy_fdwdecl.h"
// ********************************************************************************
@@ -165,7 +165,9 @@ bool WiFiConnected() {
if ((WiFiEventData.timerAPstart.isSet()) && WiFiEventData.timerAPstart.timeReached()) {
// Timer reached, so enable AP mode.
if (!WifiIsAP(WiFi.getMode())) {
setAP(true);
if (!Settings.DoNotStartAP()) {
setAP(true);
}
}
WiFiEventData.timerAPstart.clear();
}
@@ -288,7 +290,9 @@ bool prepareWiFi() {
WiFiEventData.wifiConnectAttemptNeeded = false;
// No need to wait longer to start AP mode.
setAP(true);
if (!Settings.DoNotStartAP()) {
setAP(true);
}
return false;
}
WiFiEventData.warnedNoValidWiFiSettings = false;
@@ -1,9 +1,9 @@
#include "ESPEasyWifi_ProcessEvent.h"
#include "../ESPEasyCore/ESPEasyWifi_ProcessEvent.h"
// FIXME TD-er: Rename this to ESPEasyNetwork_ProcessEvent
#include "../../ESPEasy-Globals.h"
#include "../../ESPEasy_fdwdecl.h"
#include "../ESPEasyCore/ESPEasy_Log.h"
#include "../ESPEasyCore/ESPEasyNetwork.h"
#include "../ESPEasyCore/ESPEasyWifi.h"
+1 -1
View File
@@ -1,4 +1,4 @@
#include "ESPEasy_Log.h"
#include "../ESPEasyCore/ESPEasy_Log.h"
#include "../DataStructs/LogStruct.h"
#include "../ESPEasyCore/Serial.h"
@@ -0,0 +1,114 @@
#include "../ESPEasyCore/ESPEasy_backgroundtasks.h"
#include "../../ESPEasy-Globals.h"
#include "../../ESPEasy_common.h"
#include "../DataStructs/TimingStats.h"
#include "../ESPEasyCore/ESPEasyNetwork.h"
#include "../ESPEasyCore/Serial.h"
#include "../Globals/NetworkState.h"
#include "../Globals/Services.h"
#include "../Globals/Settings.h"
#include "../Helpers/Network.h"
#include "../Helpers/Networking.h"
/*********************************************************************************************\
* run background tasks
\*********************************************************************************************/
bool runningBackgroundTasks = false;
void backgroundtasks()
{
// checkRAM(F("backgroundtasks"));
// always start with a yield
delay(0);
/*
// Remove this watchdog feed for now.
// See https://github.com/letscontrolit/ESPEasy/issues/1722#issuecomment-419659193
#ifdef ESP32
// Have to find a similar function to call ESP32's esp_task_wdt_feed();
#else
ESP.wdtFeed();
#endif
*/
// prevent recursion!
if (runningBackgroundTasks)
{
return;
}
START_TIMER
const bool networkConnected = NetworkConnected();
runningBackgroundTasks = true;
/*
// Not needed anymore, see: https://arduino-esp8266.readthedocs.io/en/latest/faq/readme.html#how-to-clear-tcp-pcbs-in-time-wait-state
if (networkConnected) {
#if defined(ESP8266)
tcpCleanup();
#endif
}
*/
process_serialWriteBuffer();
if (!UseRTOSMultitasking) {
serial();
if (webserverRunning) {
web_server.handleClient();
}
if (networkConnected) {
checkUDP();
}
}
#ifdef FEATURE_DNS_SERVER
// process DNS, only used if the ESP has no valid WiFi config
if (dnsServerActive) {
dnsServer.processNextRequest();
}
#endif // ifdef FEATURE_DNS_SERVER
#ifdef FEATURE_ARDUINO_OTA
if (Settings.ArduinoOTAEnable && networkConnected) {
ArduinoOTA.handle();
}
// once OTA is triggered, only handle that and dont do other stuff. (otherwise it fails)
while (ArduinoOTAtriggered)
{
delay(0);
if (NetworkConnected()) {
ArduinoOTA.handle();
}
}
#endif // ifdef FEATURE_ARDUINO_OTA
#ifdef FEATURE_MDNS
// Allow MDNS processing
if (networkConnected) {
# ifdef ESP8266
// ESP32 does not have an update() function
MDNS.update();
# endif // ifdef ESP8266
}
#endif // ifdef FEATURE_MDNS
delay(0);
statusLED(false);
runningBackgroundTasks = false;
STOP_TIMER(BACKGROUND_TASKS);
}
@@ -0,0 +1,9 @@
#ifndef ESPEASYCORE_ESPEASY_BACKGROUNDTASKS_H
#define ESPEASYCORE_ESPEASY_BACKGROUNDTASKS_H
/*********************************************************************************************\
* run background tasks
\*********************************************************************************************/
void backgroundtasks();
#endif
+126
View File
@@ -0,0 +1,126 @@
#include "../ESPEasyCore/ESPEasy_loop.h"
#include "../../ESPEasy-Globals.h"
#include "../DataStructs/TimingStats.h"
#include "../ESPEasyCore/ESPEasyNetwork.h"
#include "../ESPEasyCore/ESPEasyWifi_ProcessEvent.h"
#include "../ESPEasyCore/ESPEasy_backgroundtasks.h"
#include "../ESPEasyCore/ESPEasy_Log.h"
#include "../Globals/ESPEasy_Scheduler.h"
#include "../Globals/EventQueue.h"
#include "../Globals/RTC.h"
#include "../Globals/Settings.h"
#include "../Globals/Statistics.h"
#include "../Helpers/DeepSleep.h"
#include "../Helpers/ESPEasyRTC.h"
#include "../Helpers/ESPEasy_time_calc.h"
#include "../Helpers/Misc.h"
#include "../Helpers/Networking.h"
#include "../Helpers/PeriodicalActions.h"
void updateLoopStats() {
++loopCounter;
++loopCounter_full;
if (lastLoopStart == 0) {
lastLoopStart = micros();
return;
}
const long usecSince = usecPassedSince(lastLoopStart);
#ifdef USES_TIMING_STATS
miscStats[LOOP_STATS].add(usecSince);
#endif // ifdef USES_TIMING_STATS
loop_usec_duration_total += usecSince;
lastLoopStart = micros();
if ((usecSince <= 0) || (usecSince > 10000000)) {
return; // No loop should take > 10 sec.
}
if (shortestLoop > static_cast<unsigned long>(usecSince)) {
shortestLoop = usecSince;
loopCounterMax = 30 * 1000000 / usecSince;
}
if (longestLoop < static_cast<unsigned long>(usecSince)) {
longestLoop = usecSince;
}
}
/*********************************************************************************************\
* MAIN LOOP
\*********************************************************************************************/
void ESPEasy_loop()
{
/*
//FIXME TD-er: No idea what this does.
if(MainLoopCall_ptr)
MainLoopCall_ptr();
*/
dummyString = String(); // Fixme TD-er Make sure this global variable doesn't keep memory allocated.
updateLoopStats();
handle_unprocessedNetworkEvents();
bool firstLoopConnectionsEstablished = NetworkConnected() && firstLoop;
if (firstLoopConnectionsEstablished) {
addLog(LOG_LEVEL_INFO, F("firstLoopConnectionsEstablished"));
firstLoop = false;
timerAwakeFromDeepSleep = millis(); // Allow to run for "awake" number of seconds, now we have wifi.
// schedule_all_task_device_timers(); // Disabled for now, since we are now using queues for controllers.
if (Settings.UseRules && isDeepSleepEnabled())
{
String event = F("System#NoSleep=");
event += Settings.deepSleep_wakeTime;
eventQueue.addMove(std::move(event));
}
RTC.bootFailedCount = 0;
saveToRTC();
sendSysInfoUDP(1);
}
// Work around for nodes that do not have WiFi connection for a long time and may reboot after N unsuccessful connect attempts
if (getUptimeMinutes() > 2) {
// Apparently the uptime is already a few minutes. Let's consider it a successful boot.
RTC.bootFailedCount = 0;
saveToRTC();
}
// Deep sleep mode, just run all tasks one (more) time and go back to sleep as fast as possible
if ((firstLoopConnectionsEstablished || readyForSleep()) && isDeepSleepEnabled())
{
#ifdef USES_MQTT
runPeriodicalMQTT();
#endif // USES_MQTT
// Now run all frequent tasks
run50TimesPerSecond();
run10TimesPerSecond();
runEach30Seconds();
runOncePerSecond();
}
// normal mode, run each task when its time
else
{
if (!UseRTOSMultitasking) {
// On ESP32 the schedule is executed on the 2nd core.
Scheduler.handle_schedule();
}
}
backgroundtasks();
if (readyForSleep()) {
prepare_deepSleep(Settings.Delay);
// deepsleep will never return, its a special kind of reboot
}
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef ESPEASYCORE_ESPEASY_LOOP_H
#define ESPEASYCORE_ESPEASY_LOOP_H
#include "../../ESPEasy_common.h"
/*********************************************************************************************\
* MAIN LOOP
\*********************************************************************************************/
void ESPEasy_loop();
#endif
+366
View File
@@ -0,0 +1,366 @@
#include "../ESPEasyCore/ESPEasy_setup.h"
#include "../../ESPEasy_fdwdecl.h" // Needed for PluginInit() and CPluginInit()
#include "../../ESPEasy-Globals.h"
#include "../../_Plugin_Helper.h"
#include "../ESPEasyCore/ESPEasyNetwork.h"
#include "../ESPEasyCore/ESPEasyRules.h"
#include "../ESPEasyCore/ESPEasyWifi.h"
#include "../ESPEasyCore/Serial.h"
#include "../Globals/Cache.h"
#include "../Globals/ESPEasyWiFiEvent.h"
#include "../Globals/ESPEasy_time.h"
#include "../Globals/NetworkState.h"
#include "../Globals/RTC.h"
#include "../Globals/Statistics.h"
#include "../Globals/WiFi_AP_Candidates.h"
#include "../Helpers/DeepSleep.h"
#include "../Helpers/ESPEasyRTC.h"
#include "../Helpers/ESPEasy_FactoryDefault.h"
#include "../Helpers/ESPEasy_Storage.h"
#include "../Helpers/ESPEasy_checks.h"
#include "../Helpers/Hardware.h"
#include "../Helpers/Memory.h"
#include "../Helpers/Misc.h"
#include "../Helpers/StringGenerator_System.h"
#include "../WebServer/WebServer.h"
#ifdef USE_RTOS_MULTITASKING
# include "../Helpers/Networking.h"
# include "../Helpers/PeriodicalActions.h"
#endif // ifdef USE_RTOS_MULTITASKING
#ifdef FEATURE_ARDUINO_OTA
# include "../Helpers/OTA.h"
#endif // ifdef FEATURE_ARDUINO_OTA
#ifdef USE_RTOS_MULTITASKING
void RTOS_TaskServers(void *parameter)
{
while (true) {
delay(100);
web_server.handleClient();
checkUDP();
}
}
void RTOS_TaskSerial(void *parameter)
{
while (true) {
delay(100);
serial();
}
}
void RTOS_Task10ps(void *parameter)
{
while (true) {
delay(100);
run10TimesPerSecond();
}
}
void RTOS_HandleSchedule(void *parameter)
{
while (true) {
Scheduler.handle_schedule();
}
}
#endif // ifdef USE_RTOS_MULTITASKING
/*********************************************************************************************\
* ISR call back function for handling the watchdog.
\*********************************************************************************************/
void sw_watchdog_callback(void *arg)
{
yield(); // feed the WD
++sw_watchdog_callback_count;
}
/*********************************************************************************************\
* SETUP
\*********************************************************************************************/
void ESPEasy_setup()
{
#ifdef ESP8266_DISABLE_EXTRA4K
disable_extra4k_at_link_time();
#endif // ifdef ESP8266_DISABLE_EXTRA4K
#ifdef PHASE_LOCKED_WAVEFORM
enablePhaseLockedWaveform();
#endif // ifdef PHASE_LOCKED_WAVEFORM
initWiFi();
run_compiletime_checks();
#ifndef BUILD_NO_RAM_TRACKER
lowestFreeStack = getFreeStackWatermark();
lowestRAM = FreeMem();
#endif // ifndef BUILD_NO_RAM_TRACKER
#ifdef ESP8266
// ets_isr_attach(8, sw_watchdog_callback, NULL); // Set a callback for feeding the watchdog.
#endif // ifdef ESP8266
// Read ADC at boot, before WiFi tries to connect.
// see https://github.com/letscontrolit/ESPEasy/issues/2646
#if FEATURE_ADC_VCC
vcc = ESP.getVcc() / 1000.0f;
#endif // if FEATURE_ADC_VCC
#ifdef ESP8266
espeasy_analogRead(A0);
#endif // ifdef ESP8266
initAnalogWrite();
resetPluginTaskData();
#ifndef BUILD_NO_RAM_TRACKER
checkRAM(F("setup"));
#endif // ifndef BUILD_NO_RAM_TRACKER
Serial.begin(115200);
// serialPrint("\n\n\nBOOOTTT\n\n\n");
initLog();
if (SpiffsSectors() < 32)
{
serialPrintln(F("\nNo (or too small) FS area..\nSystem Halted\nPlease reflash with 128k FS minimum!"));
while (true) {
delay(1);
}
}
emergencyReset();
String log = F("\n\n\rINIT : Booting version: ");
log += getValue(LabelType::GIT_BUILD);
log += " (";
log += getSystemLibraryString();
log += ')';
addLog(LOG_LEVEL_INFO, log);
log = F("INIT : Free RAM:");
log += FreeMem();
addLog(LOG_LEVEL_INFO, log);
readBootCause();
log = F("INIT : ");
log += getLastBootCauseString();
if (readFromRTC())
{
RTC.bootFailedCount++;
RTC.bootCounter++;
lastMixedSchedulerId_beforereboot = RTC.lastMixedSchedulerId;
readUserVarFromRTC();
if (RTC.deepSleepState != 1)
{
node_time.restoreLastKnownUnixTime(RTC.lastSysTime, RTC.deepSleepState);
}
log += F(" #");
log += RTC.bootCounter;
#ifndef BUILD_NO_DEBUG
log += F(" Last Action before Reboot: ");
log += ESPEasy_Scheduler::decodeSchedulerId(lastMixedSchedulerId_beforereboot);
log += F(" Last systime: ");
log += RTC.lastSysTime;
#endif // ifndef BUILD_NO_DEBUG
}
// cold boot (RTC memory empty)
else
{
initRTC();
// cold boot situation
if (lastBootCause == BOOT_CAUSE_MANUAL_REBOOT) { // only set this if not set earlier during boot stage.
lastBootCause = BOOT_CAUSE_COLD_BOOT;
}
log = F("INIT : Cold Boot");
}
log += F(" - Restart Reason: ");
log += getResetReasonString();
RTC.deepSleepState = 0;
saveToRTC();
addLog(LOG_LEVEL_INFO, log);
fileSystemCheck();
// progMemMD5check();
LoadSettings();
Settings.UseRTOSMultitasking = false; // For now, disable it, we experience heap corruption.
if ((RTC.bootFailedCount > 10) && (RTC.bootCounter > 10)) {
byte toDisable = RTC.bootFailedCount - 10;
toDisable = disablePlugin(toDisable);
if (toDisable != 0) {
toDisable = disableController(toDisable);
}
if (toDisable != 0) {
toDisable = disableNotification(toDisable);
}
}
#ifdef HAS_ETHERNET
// This ensures, that changing WIFI OR ETHERNET MODE happens properly only after reboot. Changing without reboot would not be a good idea.
// This only works after LoadSettings();
setNetworkMedium(Settings.NetworkMedium);
#endif // ifdef HAS_ETHERNET
if (active_network_medium == NetworkMedium_t::WIFI) {
if (!WiFi_AP_Candidates.hasKnownCredentials()) {
WiFiEventData.wifiSetup = true;
RTC.clearLastWiFi(); // Must scan all channels
// Wait until scan has finished to make sure as many as possible are found
// We're still in the setup phase, so nothing else is taking resources of the ESP.
WifiScan(false);
WiFiEventData.lastScanMoment.clear();
}
// Start an extra async scan so we can continue, but we may find more APs by scanning twice.
WifiScan(true);
}
// setWifiMode(WIFI_STA);
checkRuleSets();
// if different version, eeprom settings structure has changed. Full Reset needed
// on a fresh ESP module eeprom values are set to 255. Version results into -1 (signed int)
if ((Settings.Version != VERSION) || (Settings.PID != ESP_PROJECT_PID))
{
// Direct Serial is allowed here, since this is only an emergency task.
serialPrint(F("\nPID:"));
serialPrintln(String(Settings.PID));
serialPrint(F("Version:"));
serialPrintln(String(Settings.Version));
serialPrintln(F("INIT : Incorrect PID or version!"));
delay(1000);
ResetFactory();
}
initSerial();
if (Settings.Build != BUILD) {
BuildFixes();
}
log = F("INIT : Free RAM:");
log += FreeMem();
addLog(LOG_LEVEL_INFO, log);
if (Settings.UseSerial && (Settings.SerialLogLevel >= LOG_LEVEL_DEBUG_MORE)) {
Serial.setDebugOutput(true);
}
#ifndef BUILD_NO_RAM_TRACKER
checkRAM(F("hardwareInit"));
#endif // ifndef BUILD_NO_RAM_TRACKER
hardwareInit();
timermqtt_interval = 250; // Interval for checking MQTT
timerAwakeFromDeepSleep = millis();
CPluginInit();
#ifdef USES_NOTIFIER
NPluginInit();
#endif // ifdef USES_NOTIFIER
PluginInit();
log = F("INFO : Plugins: ");
log += deviceCount + 1;
log += ' ';
log += getPluginDescriptionString();
log += " (";
log += getSystemLibraryString();
log += ')';
addLog(LOG_LEVEL_INFO, log);
if (deviceCount + 1 >= PLUGIN_MAX) {
addLog(LOG_LEVEL_ERROR, String(F("Programming error! - Increase PLUGIN_MAX (")) + deviceCount + ')');
}
clearAllCaches();
if (Settings.UseRules && isDeepSleepEnabled())
{
String event = F("System#NoSleep=");
event += Settings.deepSleep_wakeTime;
rulesProcessing(event); // TD-er: Process events in the setup() now.
}
if (Settings.UseRules)
{
String event = F("System#Wake");
rulesProcessing(event); // TD-er: Process events in the setup() now.
}
NetworkConnectRelaxed();
setWebserverRunning(true);
#ifdef FEATURE_REPORTING
ReportStatus();
#endif // ifdef FEATURE_REPORTING
#ifdef FEATURE_ARDUINO_OTA
ArduinoOTAInit();
#endif // ifdef FEATURE_ARDUINO_OTA
if (node_time.systemTimePresent()) {
node_time.initTime();
}
if (Settings.UseRules)
{
String event = F("System#Boot");
rulesProcessing(event); // TD-er: Process events in the setup() now.
}
writeDefaultCSS();
UseRTOSMultitasking = Settings.UseRTOSMultitasking;
#ifdef USE_RTOS_MULTITASKING
if (UseRTOSMultitasking) {
log = F("RTOS : Launching tasks");
addLog(LOG_LEVEL_INFO, log);
xTaskCreatePinnedToCore(RTOS_TaskServers, "RTOS_TaskServers", 16384, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(RTOS_TaskSerial, "RTOS_TaskSerial", 8192, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(RTOS_Task10ps, "RTOS_Task10ps", 8192, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(
RTOS_HandleSchedule, /* Function to implement the task */
"RTOS_HandleSchedule", /* Name of the task */
16384, /* Stack size in words */
NULL, /* Task input parameter */
1, /* Priority of the task */
NULL, /* Task handle. */
1); /* Core where the task should run */
}
#endif // ifdef USE_RTOS_MULTITASKING
// Start the interval timers at N msec from now.
// Make sure to start them at some time after eachother,
// since they will keep running at the same interval.
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_20MSEC, 5); // timer for periodic actions 50 x per/sec
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_100MSEC, 66); // timer for periodic actions 10 x per/sec
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_1SEC, 777); // timer for periodic actions once per/sec
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_30SEC, 1333); // timer for watchdog once per 30 sec
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_MQTT, 88); // timer for interaction with MQTT
Scheduler.setIntervalTimerOverride(ESPEasy_Scheduler::IntervalTimer_e::TIMER_STATISTICS, 2222);
}
+11
View File
@@ -0,0 +1,11 @@
#ifndef ESPEASYCORE_ESPEASY_SETUP_H
#define ESPEASYCORE_ESPEASY_SETUP_H
#include "../../ESPEasy_common.h"
/*********************************************************************************************\
* SETUP
\*********************************************************************************************/
void ESPEasy_setup();
#endif
+1 -1
View File
@@ -1,3 +1,3 @@
#include "ESPEasy_Scheduler.h"
#include "../Globals/ESPEasy_Scheduler.h"
ESPEasy_Scheduler Scheduler;
+1 -1
View File
@@ -1,4 +1,4 @@
#include "DeepSleep.h"
#include "../Helpers/DeepSleep.h"
#include "../../ESPEasy_common.h"
#include "../../ESPEasy-Globals.h"
+1 -1
View File
@@ -1,4 +1,4 @@
#include "ESPEasyRTC.h"
#include "../Helpers/ESPEasyRTC.h"
#include "../Globals/RTC.h"
#include "../DataStructs/RTCStruct.h"
+1 -1
View File
@@ -1,4 +1,4 @@
#include "ESPEasy_FactoryDefault.h"
#include "../Helpers/ESPEasy_FactoryDefault.h"
#include "../../ESPEasy_common.h"
#include "../../_Plugin_Helper.h"
+1 -1
View File
@@ -1,4 +1,4 @@
#include "ESPEasy_checks.h"
#include "../Helpers/ESPEasy_checks.h"
#include "../../ESPEasy_common.h"
+19 -7
View File
@@ -1,15 +1,12 @@
#include "Misc.h"
#include "../Helpers/Misc.h"
#include "../../ESPEasy-Globals.h"
#include "../../ESPEasy_common.h"
#include "../../_Plugin_Helper.h"
#include "../../ESPEasy_fdwdecl.h"
#include "../../ESPEasy-Globals.h"
#include "../ESPEasyCore/ESPEasy_backgroundtasks.h"
#include "../ESPEasyCore/Serial.h"
#include "../Globals/ESPEasy_time.h"
#include "../Globals/Statistics.h"
#include "../Helpers/ESPEasy_FactoryDefault.h"
#include "../Helpers/ESPEasy_Storage.h"
#include "../Helpers/Numerical.h"
@@ -18,6 +15,8 @@
#include "../Helpers/StringParser.h"
bool remoteConfig(struct EventStruct *event, const String& string)
{
// FIXME TD-er: Why have an event here as argument? It is not used.
@@ -417,3 +416,16 @@ void set4BitToUL(uint32_t& number, byte bitnr, uint8_t value) {
number = (number & ~mask) | newvalue;
}
float getCPUload() {
return 100.0f - Scheduler.getIdleTimePct();
}
int getLoopCountPerSec() {
return loopCounterLast / 30;
}
int getUptimeMinutes() {
return wdcounter / 2;
}
+7
View File
@@ -165,4 +165,11 @@ void set4BitToUL(uint32_t& number,
uint8_t value);
float getCPUload();
int getLoopCountPerSec();
int getUptimeMinutes();
#endif // ifndef HELPERS_MISC_H
+1 -1
View File
@@ -1,4 +1,4 @@
#include "Networking.h"
#include "../Helpers/Networking.h"
#include "../../ESPEasy_common.h"
#include "../Commands/InternalCommands.h"
+1 -1
View File
@@ -1,4 +1,4 @@
#include "Numerical.h"
#include "../Helpers/Numerical.h"
/********************************************************************************************\
Check if string is valid float
+1 -1
View File
@@ -1,4 +1,4 @@
#include "OTA.h"
#include "../Helpers/OTA.h"
#include "../ESPEasyCore/ESPEasy_Log.h"
#include "../ESPEasyCore/Serial.h"
+40 -2
View File
@@ -1,7 +1,7 @@
#include "../Helpers/PeriodicalActions.h"
#include "../../ESPEasy_common.h"
#include "../../ESPEasy_fdwdecl.h"
#include "../../ESPEasy-Globals.h"
#include "../ControllerQueue/DelayQueueElements.h"
@@ -36,6 +36,11 @@
#include "../Helpers/StringGenerator_WiFi.h"
#include "../Helpers/StringProvider.h"
#ifdef USES_C015
#include "../../ESPEasy_fdwdecl.h"
#endif
#define PLUGIN_ID_MQTT_IMPORT 37
@@ -287,7 +292,12 @@ void schedule_all_tasks_using_MQTT_controller() {
}
void processMQTTdelayQueue() {
if (MQTTDelayHandler == nullptr || !MQTTclient_connected) {
if (MQTTDelayHandler == nullptr) {
return;
}
runPeriodicalMQTT(); // Update MQTT connected state.
if (!MQTTclient_connected) {
scheduleNextMQTTdelayQueue();
return;
}
@@ -437,6 +447,34 @@ void updateLoopStats_30sec(byte loglevel) {
/********************************************************************************************\
Clean up all before going to sleep or reboot.
\*********************************************************************************************/
void flushAndDisconnectAllClients() {
if (anyControllerEnabled()) {
#ifdef USES_MQTT
bool mqttControllerEnabled = validControllerIndex(firstEnabledMQTT_ControllerIndex());
#endif //USES_MQTT
unsigned long timer = millis() + 1000;
while (!timeOutReached(timer)) {
// call to all controllers (delay queue) to flush all data.
CPluginCall(CPlugin::Function::CPLUGIN_FLUSH, 0);
#ifdef USES_MQTT
if (mqttControllerEnabled && MQTTclient.connected()) {
MQTTclient.loop();
}
#endif //USES_MQTT
}
#ifdef USES_MQTT
if (mqttControllerEnabled && MQTTclient.connected()) {
MQTTclient.disconnect();
updateMQTTclient_connected();
}
#endif //USES_MQTT
saveToRTC();
delay(100); // Flush anything in the network buffers.
}
process_serialWriteBuffer();
}
void prepareShutdown(ESPEasy_Scheduler::IntendedRebootReason_e reason)
{
#ifdef USES_MQTT
+3 -5
View File
@@ -1,7 +1,7 @@
#include "Scheduler.h"
#include "../Helpers/Scheduler.h"
#include "../../ESPEasy_common.h"
#include "../../ESPEasy_fdwdecl.h"
#include "../../ESPEasy-Globals.h"
#include "../../_Plugin_Helper.h"
@@ -19,9 +19,7 @@
#include "../Helpers/PortStatus.h"
//#define TIMER_ID_SHIFT 28 // Must be decreased as soon as timers below reach 15
#define TIMER_ID_SHIFT 28 // Must be decreased as soon as timers below reach 15
#define TIMER_ID_SHIFT 28 // Must be decreased as soon as timers below reach 15
#define SYSTEM_EVENT_QUEUE 0 // Not really a timer.
#define CONST_INTERVAL_TIMER 1
#define PLUGIN_TASK_TIMER 2
+1 -1
View File
@@ -1,4 +1,4 @@
#include "StringGenerator_System.h"
#include "../Helpers/StringGenerator_System.h"
#include <Arduino.h>
+2 -1
View File
@@ -3,7 +3,7 @@
#ifdef HAS_ETHERNET
# include "ETH.h"
#endif // ifdef HAS_ETHERNET
#include "../../ESPEasy_fdwdecl.h"
#include "../../ESPEasy-Globals.h"
#include "../ESPEasyCore/ESPEasyNetwork.h"
@@ -22,6 +22,7 @@
#include "../Helpers/CompiletimeDefines.h"
#include "../Helpers/Memory.h"
#include "../Helpers/Misc.h"
#include "../Helpers/Scheduler.h"
#include "../Helpers/StringConverter.h"
#include "../Helpers/StringGenerator_System.h"
+2 -1
View File
@@ -2,7 +2,7 @@
#include "../../ESPEasy_common.h"
#include "../../ESPEasy_fdwdecl.h"
#include "../../ESPEasy-Globals.h"
#include "../DataStructs/TimingStats.h"
@@ -23,6 +23,7 @@
#include "../Helpers/CompiletimeDefines.h"
#include "../Helpers/Hardware.h"
#include "../Helpers/Misc.h"
#include "../Helpers/Numerical.h"
#include "../Helpers/StringConverter.h"
#include "../Helpers/StringProvider.h"
+2 -1
View File
@@ -4,9 +4,10 @@
#include "../Globals/RTC.h"
#include "../Globals/SecuritySettings.h"
#include "../Globals/Settings.h"
#include "../Helpers/Misc.h"
#include "../../ESPEasy_common.h"
#include "../../ESPEasy_fdwdecl.h"
#define WIFI_CUSTOM_DEPLOYMENT_KEY_INDEX 3
#define WIFI_CUSTOM_SUPPORT_KEY_INDEX 4
+2 -1
View File
@@ -1,7 +1,7 @@
#include "../Helpers/_CPlugin_Helper.h"
#include "../../ESPEasy_common.h"
#include "../../ESPEasy_fdwdecl.h"
#include "../CustomBuild/ESPEasyLimits.h"
@@ -11,6 +11,7 @@
#include "../DataStructs/ControllerSettingsStruct.h"
#include "../DataStructs/TimingStats.h"
#include "../ESPEasyCore/ESPEasy_backgroundtasks.h"
#include "../ESPEasyCore/ESPEasy_Log.h"
#include "../ESPEasyCore/ESPEasyEth.h"
#include "../ESPEasyCore/ESPEasyNetwork.h"
+2
View File
@@ -6,12 +6,14 @@
#include "../../ESPEasy_common.h"
#include "../../_Plugin_Helper.h"
#include "../ControllerQueue/DelayQueueElements.h"
#include "../ESPEasyCore/Controller.h"
#include "../ESPEasyCore/ESPEasyNetwork.h"
#include "../Globals/CPlugins.h"
#include "../Globals/ESPEasy_Scheduler.h"
#include "../Helpers/Misc.h"
#include "../Helpers/Network.h"
#include "../Helpers/Numerical.h"
#include "../Helpers/StringConverter.h"
#include "../Helpers/_CPlugin_Helper_webform.h"
+171 -2
View File
@@ -1,6 +1,6 @@
#include "../PluginStructs/P012_data_struct.h"
// Needed also here for PlatformIO's library finder as the .h file
// Needed also here for PlatformIO's library finder as the .h file
// is in a directory which is excluded in the src_filter
#include <LiquidCrystal_I2C.h>
@@ -35,6 +35,7 @@ P012_data_struct::P012_data_struct(uint8_t addr,
lcd.init(); // initialize the lcd
lcd.backlight();
lcd.print(F("ESP Easy"));
createCustomChars();
}
void P012_data_struct::setBacklightTimer(byte timer) {
@@ -104,4 +105,172 @@ void P012_data_struct::lcdWrite(const String& text, byte col, byte row) {
}
}
#endif // ifdef USES_P012
// Perform some specific changes for LCD display
// https://www.letscontrolit.com/forum/viewtopic.php?t=2368
String P012_data_struct::P012_parseTemplate(String& tmpString, byte lineSize) {
String result = parseTemplate_padded(tmpString, lineSize);
const char degree[3] = { 0xc2, 0xb0, 0 }; // Unicode degree symbol
const char degree_lcd[2] = { 0xdf, 0 }; // P012_LCD degree symbol
result.replace(degree, degree_lcd);
char unicodePrefix = 0xc4;
# ifdef USES_P012_POLISH_CHARS
if (result.indexOf(unicodePrefix) != -1) {
const char znak_a_uni[3] = { 0xc4, 0x85, 0 }; // Unicode znak a
const char znak_a_lcd[2] = { 0x05, 0 }; // P012_LCD znak a
result.replace(znak_a_uni, znak_a_lcd);
const char znak_A_uni[3] = { 0xc4, 0x84, 0 }; // Unicode znak A
result.replace(znak_A_uni, znak_a_lcd);
const char znak_c_uni[3] = { 0xc4, 0x87, 0 }; // Unicode znak c
const char znak_c_lcd[2] = { 0x03, 0 }; // P012_LCD znak c
result.replace(znak_c_uni, znak_c_lcd);
const char znak_C_uni[3] = { 0xc4, 0x86, 0 }; // Unicode znak C
result.replace(znak_C_uni, znak_c_lcd);
const char znak_e_uni[3] = { 0xc4, 0x99, 0 }; // Unicode znak e
const char znak_e_lcd[2] = { 0x02, 0 }; // P012_LCD znak e
result.replace(znak_e_uni, znak_e_lcd);
const char znak_E_uni[3] = { 0xc4, 0x98, 0 }; // Unicode znak E
result.replace(znak_E_uni, znak_e_lcd);
}
unicodePrefix = 0xc5;
if (result.indexOf(unicodePrefix) != -1) {
const char znak_l_uni[3] = { 0xc5, 0x82, 0 }; // Unicode znak l
const char znak_l_lcd[2] = { 0x01, 0 }; // P012_LCD znak l
result.replace(znak_l_uni, znak_l_lcd);
const char znak_L_uni[3] = { 0xc5, 0x81, 0 }; // Unicode znak L
result.replace(znak_L_uni, znak_l_lcd);
const char znak_n_uni[3] = { 0xc5, 0x84, 0 }; // Unicode znak n
const char znak_n_lcd[2] = { 0x04, 0 }; // P012_LCD znak n
result.replace(znak_n_uni, znak_n_lcd);
const char znak_N_uni[3] = { 0xc5, 0x83, 0 }; // Unicode znak N
result.replace(znak_N_uni, znak_n_lcd);
const char znak_s_uni[3] = { 0xc5, 0x9b, 0 }; // Unicode znak s
const char znak_s_lcd[2] = { 0x06, 0 }; // P012_LCD znak s
result.replace(znak_s_uni, znak_s_lcd);
const char znak_S_uni[3] = { 0xc5, 0x9a, 0 }; // Unicode znak S
result.replace(znak_S_uni, znak_s_lcd);
const char znak_z1_uni[3] = { 0xc5, 0xba, 0 }; // Unicode znak z z kreska
const char znak_z1_lcd[2] = { 0x07, 0 }; // P012_LCD znak z z kropka
result.replace(znak_z1_uni, znak_z1_lcd);
const char znak_Z1_uni[3] = { 0xc5, 0xb9, 0 }; // Unicode znak Z z kreska
result.replace(znak_Z1_uni, znak_z1_lcd);
const char znak_z2_uni[3] = { 0xc5, 0xbc, 0 }; // Unicode znak z z kropka
const char znak_z2_lcd[2] = { 0x07, 0 }; // P012_LCD znak z z kropka
result.replace(znak_z2_uni, znak_z2_lcd);
const char znak_Z2_uni[3] = { 0xc5, 0xbb, 0 }; // Unicode znak Z z kropka
result.replace(znak_Z2_uni, znak_z2_lcd);
}
unicodePrefix = 0xc3;
if (result.indexOf(unicodePrefix) != -1) {
const char znak_o_uni[3] = { 0xc3, 0xB3, 0 }; // Unicode znak o
const char znak_o_lcd[2] = { 0x08, 0 }; // P012_LCD znak o
result.replace(znak_o_uni, znak_o_lcd);
const char znak_O_uni[3] = { 0xc3, 0x93, 0 }; // Unicode znak O
result.replace(znak_O_uni, znak_o_lcd);
}
# endif // USES_P012_POLISH_CHARS
unicodePrefix = 0xc3;
if (result.indexOf(unicodePrefix) != -1) {
// See: https://github.com/letscontrolit/ESPEasy/issues/2081
const char umlautAE_uni[3] = { 0xc3, 0x84, 0 }; // Unicode Umlaute AE
const char umlautAE_lcd[2] = { 0xe1, 0 }; // P012_LCD Umlaute
result.replace(umlautAE_uni, umlautAE_lcd);
const char umlaut_ae_uni[3] = { 0xc3, 0xa4, 0 }; // Unicode Umlaute ae
result.replace(umlaut_ae_uni, umlautAE_lcd);
const char umlautOE_uni[3] = { 0xc3, 0x96, 0 }; // Unicode Umlaute OE
const char umlautOE_lcd[2] = { 0xef, 0 }; // P012_LCD Umlaute
result.replace(umlautOE_uni, umlautOE_lcd);
const char umlaut_oe_uni[3] = { 0xc3, 0xb6, 0 }; // Unicode Umlaute oe
result.replace(umlaut_oe_uni, umlautOE_lcd);
const char umlautUE_uni[3] = { 0xc3, 0x9c, 0 }; // Unicode Umlaute UE
const char umlautUE_lcd[2] = { 0xf5, 0 }; // P012_LCD Umlaute
result.replace(umlautUE_uni, umlautUE_lcd);
const char umlaut_ue_uni[3] = { 0xc3, 0xbc, 0 }; // Unicode Umlaute ue
result.replace(umlaut_ue_uni, umlautUE_lcd);
const char umlaut_sz_uni[3] = { 0xc3, 0x9f, 0 }; // Unicode Umlaute sz
const char umlaut_sz_lcd[2] = { 0xe2, 0 }; // P012_LCD Umlaute
result.replace(umlaut_sz_uni, umlaut_sz_lcd);
}
return result;
}
void P012_data_struct::createCustomChars() {
# ifdef USES_P012_POLISH_CHARS
/*
static const char LETTER_null[8] PROGMEM = { // spacja
0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000
};
*/
static const char LETTER_a[8] PROGMEM = { // a
0b00000, 0b00000, 0b01110, 0b00001, 0b01111, 0b10001, 0b01111, 0b00010
};
static const char LETTER_c[8] PROGMEM = { // c
0b00010, 0b00100, 0b01110, 0b10000, 0b10000, 0b10001, 0b01110, 0b00000
};
static const char LETTER_e[8] PROGMEM = { // e
0b00000, 0b00000, 0b01110, 0b10001, 0b11111, 0b10000, 0b01110, 0b00010
};
static const char LETTER_l[8] PROGMEM = { // l
0b01100, 0b00100, 0b00101, 0b00110, 0b01100, 0b00100, 0b01110, 0b00000
};
static const char LETTER_n[8] PROGMEM = { // n
0b00010, 0b00100, 0b10110, 0b11001, 0b10001, 0b10001, 0b10001, 0b00000
};
static const char LETTER_o[8] PROGMEM = { // o
0b00010, 0b00100, 0b01110, 0b10001, 0b10001, 0b10001, 0b01110, 0b00000
};
static const char LETTER_s[8] PROGMEM = { // s
0b00010, 0b00100, 0b01110, 0b10000, 0b01110, 0b00001, 0b11110, 0b00000
};
/*
static const char LETTER_z1[8] PROGMEM = { // z z kreska
0b00010, 0b00100, 0b11111, 0b00010, 0b00100, 0b01000, 0b11111, 0b00000
};
*/
static const char LETTER_z2[8] PROGMEM = { // z z kropka
0b00100, 0b00000, 0b11111, 0b00010, 0b00100, 0b01000, 0b11111, 0b00000
};
lcd.createChar(0, LETTER_o); // probably defected memory cell
lcd.createChar(1, LETTER_l);
lcd.createChar(2, LETTER_e);
lcd.createChar(3, LETTER_c);
lcd.createChar(4, LETTER_n);
lcd.createChar(5, LETTER_a);
lcd.createChar(6, LETTER_s);
lcd.createChar(7, LETTER_z2);
lcd.createChar(8, LETTER_o);
# endif // ifdef USES_P012_POLISH_CHARS
}
#endif // ifdef USES_P012
+4
View File
@@ -21,6 +21,10 @@ struct P012_data_struct : public PluginTaskData_base {
byte col,
byte row);
String P012_parseTemplate(String& tmpString, byte lineSize);
void createCustomChars();
LiquidCrystal_I2C lcd;
int Plugin_012_cols = 16;
+1 -1
View File
@@ -7,7 +7,7 @@
#include "../Helpers/StringConverter.h"
#include "../Helpers/SystemVariables.h"
#include "../../ESPEasy_fdwdecl.h"
#include <XPT2046_Touchscreen.h>
@@ -0,0 +1,33 @@
#include "../PluginStructs/P112_data_struct.h"
#ifdef USES_P112
// #######################################################################################################
// #################### Plugin 112 I2C AS7265X Triad Spectroscopy Sensor and White, IR and UV LED ########
// #######################################################################################################
//
// Triad Spectroscopy Sensor and White, IR and UV LED
// like this one: https://www.sparkfun.com/products/15050
// based on this library: https://github.com/sparkfun/SparkFun_AS7265x_Arduino_Library
// this code is based on 29 Mar 2019-03-29 version of the above library
//
// 2021-03-29 heinemannj: Initial commit
//
// Needed also here for PlatformIO's library finder as the .h file
// is in a directory which is excluded in the src_filter
#include <SparkFun_AS7265X.h>
bool P112_data_struct::begin()
{
if (!initialized) {
initialized = sensor.begin();
if (initialized) {
// sensor.takeMeasurementsWithBulb();
}
}
return initialized;
}
#endif // ifdef USES_P112
+33
View File
@@ -0,0 +1,33 @@
#ifndef PLUGINSTRUCTS_P112_DATA_STRUCT_H
#define PLUGINSTRUCTS_P112_DATA_STRUCT_H
#include "../../_Plugin_Helper.h"
#ifdef USES_P112
// #######################################################################################################
// #################### Plugin 112 I2C AS7265X Triad Spectroscopy Sensor and White, IR and UV LED ########
// #######################################################################################################
//
// Triad Spectroscopy Sensor and White, IR and UV LED
// like this one: https://www.sparkfun.com/products/15050
// based on this library: https://github.com/sparkfun/SparkFun_AS7265x_Arduino_Library
// this code is based on 29 Mar 2019-03-29 version of the above library
//
// 2021-03-29 heinemannj: Initial commit
//
#include <SparkFun_AS7265X.h>
struct P112_data_struct : public PluginTaskData_base {
bool begin();
AS7265X sensor;
bool initialized = false;
// MeasurementStatus:
// 0 : Not running
// 1 - 18 : Running
byte MeasurementStatus = 0;
};
#endif // ifdef USES_P112
#endif // ifndef PLUGINSTRUCTS_P112_DATA_STRUCT_H
+11
View File
@@ -82,6 +82,9 @@ void handle_config() {
// When set you can use the Sensor in AP-Mode without being forced to /setup
Settings.ApDontForceSetup(isFormItemChecked(F("ApDontForceSetup")));
// Usually the AP will be started when no WiFi is defined, or the defined one cannot be found. This flag may prevent it.
Settings.DoNotStartAP(isFormItemChecked(F("DoNotStartAP")));
// TD-er Read access control from form.
SecuritySettings.IPblockLevel = getFormItemInt(F("ipblocklevel"));
@@ -148,6 +151,14 @@ void handle_config() {
addFormCheckBox(F("Don't force /setup in AP-Mode"), F("ApDontForceSetup"), Settings.ApDontForceSetup());
addFormNote(F("When set you can use the Sensor in AP-Mode without being forced to /setup. /setup can still be called."));
addFormCheckBox(F("Do Not Start AP"), F("DoNotStartAP"), Settings.DoNotStartAP());
#ifdef HAS_ETHERNET
addFormNote(F("Do not allow to start an AP when unable to connect to configured LAN/WiFi"));
#else
addFormNote(F("Do not allow to start an AP when configured WiFi cannot be found"));
#endif
// TD-er add IP access box F("ipblocklevel")
addFormSubHeader(F("Client IP filtering"));
{
+2 -1
View File
@@ -20,9 +20,10 @@
#include "../Globals/Statistics.h"
#include "../Helpers/ESPEasy_Storage.h"
#include "../Helpers/Memory.h"
#include "../Helpers/Misc.h"
#include "../Helpers/WebServer_commandHelper.h"
#include "../../ESPEasy_fdwdecl.h"
#include "../../ESPEasy-Globals.h"
#ifdef USES_MQTT
+2 -1
View File
@@ -5,7 +5,7 @@
#include "../WebServer/Markup.h"
#include "../WebServer/Markup_Buttons.h"
#include "../../ESPEasy_fdwdecl.h"
#include "../../ESPEasy-Globals.h"
#include "../Commands/Diagnostic.h"
@@ -26,6 +26,7 @@
#include "../Helpers/ESPEasy_Storage.h"
#include "../Helpers/Hardware.h"
#include "../Helpers/Memory.h"
#include "../Helpers/Misc.h"
#include "../Helpers/OTA.h"
#include "../Helpers/StringConverter.h"
#include "../Helpers/StringGenerator_GPIO.h"
+1 -1
View File
@@ -47,7 +47,7 @@ else:
# "-DUSES_P094", # CUL Reader
# "-DUSES_P095", # TFT ILI9341
"-DUSES_P106", # BME680
"-DUSES_P107", # SI1145 UV index
# "-DUSES_P107", # SI1145 UV index
"-DUSES_C016", # Cache Controller
"-DUSES_C018", # TTN/RN2483