Compare commits
	
		
			22 Commits
		
	
	
		
			ca26f090fa
			...
			ollo-dev
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2cf17ec7b8 | ||
| 
						 | 
					9435bf8392 | ||
| 
						 | 
					1190b0324e | ||
| 
						 | 
					cf1f631e07 | ||
| 
						 | 
					2fad7ebbaf | ||
| 
						 | 
					7d6c1c3daa | ||
| 
						 | 
					aa7cb31302 | ||
| 
						 | 
					cd1e88e6e2 | ||
| 
						 | 
					cbde8ee11c | ||
| 
						 | 
					dd3888ba52 | ||
| 
						 | 
					d2f1605b90 | ||
| 
						 | 
					cb37426fbb | ||
| 
						 | 
					48e5383106 | ||
| 
						 | 
					ff081a8d44 | ||
| 
						 | 
					3764183944 | ||
| 
						 | 
					c85f69c545 | ||
| 
						 | 
					7494f9de51 | ||
| 
						 | 
					9c4e747b50 | ||
| 
						 | 
					fb87907afc | ||
| 
						 | 
					97a88ebb91 | ||
| 
						 | 
					f8629586f8 | ||
| 
						 | 
					4f7e57988b | 
@@ -1,16 +1,41 @@
 | 
				
			|||||||
 | 
					; PlatformIO Project Configuration File
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					;   Build options: build flags, source filter
 | 
				
			||||||
 | 
					;   Upload options: custom upload port, speed and extra flags
 | 
				
			||||||
 | 
					;   Library options: dependencies, extra library storages
 | 
				
			||||||
 | 
					;   Advanced options: extra scripting
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					; Please visit documentation for the other options and examples
 | 
				
			||||||
 | 
					; https://docs.platformio.org/page/projectconf.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[env:esp32doit-devkit-v1]
 | 
					[env:esp32doit-devkit-v1]
 | 
				
			||||||
platform = espressif32
 | 
					platform = espressif32@6.3.2
 | 
				
			||||||
board = esp32doit-devkit-v1
 | 
					board = esp32doit-devkit-v1
 | 
				
			||||||
framework = arduino
 | 
					framework = arduino
 | 
				
			||||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
 | 
					build_flags = -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
 | 
				
			||||||
 | 
					    -DPLANT0_SENSORTYPE=FREQUENCY_MOD_RESISTANCE_PROBE
 | 
				
			||||||
 | 
					    -DPLANT1_SENSORTYPE=FREQUENCY_MOD_RESISTANCE_PROBE
 | 
				
			||||||
 | 
					    -DPLANT2_SENSORTYPE=FREQUENCY_MOD_RESISTANCE_PROBE
 | 
				
			||||||
 | 
					    -DPLANT3_SENSORTYPE=FREQUENCY_MOD_RESISTANCE_PROBE
 | 
				
			||||||
 | 
					    -DPLANT4_SENSORTYPE=FREQUENCY_MOD_RESISTANCE_PROBE
 | 
				
			||||||
 | 
					    -DPLANT5_SENSORTYPE=FREQUENCY_MOD_RESISTANCE_PROBE
 | 
				
			||||||
 | 
					    -DPLANT6_SENSORTYPE=FREQUENCY_MOD_RESISTANCE_PROBE
 | 
				
			||||||
 | 
					    -DTIMED_LIGHT_PIN=CUSTOM1_PIN5
 | 
				
			||||||
 | 
					    -DFLOWMETER_PIN=CUSTOM1_PIN1
 | 
				
			||||||
 | 
					    -DANALOG_WATER=GPIO_NUM_34
 | 
				
			||||||
 | 
					
 | 
				
			||||||
board_build.partitions = defaultWithSmallerSpiffs.csv
 | 
					board_build.partitions = defaultWithSmallerSpiffs.csv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					;#https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; the latest development brankitchen-lightch (convention V3.0.x) 
 | 
					; the latest development brankitchen-lightch (convention V3.0.x) 
 | 
				
			||||||
lib_deps = ArduinoJson@6.16.1
 | 
					lib_deps = bblanchon/ArduinoJson@^6.20.1
 | 
				
			||||||
            OneWire
 | 
					            paulstoffregen/OneWire@^2.3.6
 | 
				
			||||||
            DallasTemperature
 | 
					            milesburton/DallasTemperature@^3.11.0
 | 
				
			||||||
            pololu/VL53L0X
 | 
					            pololu/VL53L0X@^1.3.1
 | 
				
			||||||
            https://github.com/homieiot/homie-esp8266.git#develop
 | 
					            https://github.com/homieiot/homie-esp8266.git#develop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; add additional parameter, like the upload port
 | 
					[platformio]
 | 
				
			||||||
upload_port=/dev/ttyUSB1
 | 
					
 | 
				
			||||||
 | 
					extra_configs = custom_platformio.ini
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,8 @@ if [ ! -f $firmwareFile ]; then
 | 
				
			|||||||
	echo "the script $0 must be started in host/ sub directory"
 | 
						echo "the script $0 must be started in host/ sub directory"
 | 
				
			||||||
	exit 2
 | 
						exit 2
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					echo "Firmware changed:"
 | 
				
			||||||
 | 
					ls -l $firmwareFile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mosquitto_pub -h $mqttHost -t "${mqttPrefix}${homieId}/stay/alive/set" -m "1" -r
 | 
					mosquitto_pub -h $mqttHost -t "${mqttPrefix}${homieId}/stay/alive/set" -m "1" -r
 | 
				
			||||||
echo "Waiting ..."
 | 
					echo "Waiting ..."
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,6 +54,15 @@
 | 
				
			|||||||
#define SENSOR_PLANT5 GPIO_NUM_39 /**< SENSOR_VIN */
 | 
					#define SENSOR_PLANT5 GPIO_NUM_39 /**< SENSOR_VIN */
 | 
				
			||||||
#define SENSOR_PLANT6 GPIO_NUM_36 /**< SENSOR_VP  */
 | 
					#define SENSOR_PLANT6 GPIO_NUM_36 /**< SENSOR_VP  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HWREVISION07
 | 
				
			||||||
 | 
					#define OUTPUT_PUMP0 GPIO_NUM_17 /**< GPIO 17 */
 | 
				
			||||||
 | 
					#define OUTPUT_PUMP1 GPIO_NUM_5  /**< GPIO 5 */
 | 
				
			||||||
 | 
					#define OUTPUT_PUMP2 GPIO_NUM_18 /**< GPIO 18 */
 | 
				
			||||||
 | 
					#define OUTPUT_PUMP3 GPIO_NUM_19 /**< GPIO 19 */
 | 
				
			||||||
 | 
					#define OUTPUT_PUMP4 GPIO_NUM_21 /**< GPIO 21 */
 | 
				
			||||||
 | 
					#define OUTPUT_PUMP5 GPIO_NUM_22 /**< GPIO 22  */
 | 
				
			||||||
 | 
					#define OUTPUT_PUMP6 GPIO_NUM_23 /**< GPIO 23 */
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
#define OUTPUT_PUMP0 GPIO_NUM_15 /**< GPIO 15 */
 | 
					#define OUTPUT_PUMP0 GPIO_NUM_15 /**< GPIO 15 */
 | 
				
			||||||
#define OUTPUT_PUMP1 GPIO_NUM_5  /**< GPIO 5 */
 | 
					#define OUTPUT_PUMP1 GPIO_NUM_5  /**< GPIO 5 */
 | 
				
			||||||
#define OUTPUT_PUMP2 GPIO_NUM_18 /**< GPIO 18 */
 | 
					#define OUTPUT_PUMP2 GPIO_NUM_18 /**< GPIO 18 */
 | 
				
			||||||
@@ -61,18 +70,35 @@
 | 
				
			|||||||
#define OUTPUT_PUMP4 GPIO_NUM_21 /**< GPIO 21 */
 | 
					#define OUTPUT_PUMP4 GPIO_NUM_21 /**< GPIO 21 */
 | 
				
			||||||
#define OUTPUT_PUMP5 GPIO_NUM_22 /**< GPIO 22  */
 | 
					#define OUTPUT_PUMP5 GPIO_NUM_22 /**< GPIO 22  */
 | 
				
			||||||
#define OUTPUT_PUMP6 GPIO_NUM_23 /**< GPIO 23 */
 | 
					#define OUTPUT_PUMP6 GPIO_NUM_23 /**< GPIO 23 */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define OUTPUT_ENABLE_SENSOR GPIO_NUM_14 /**< GPIO 14 - Enable Sensors  */
 | 
					 | 
				
			||||||
#define OUTPUT_ENABLE_PUMP   GPIO_NUM_13 /**< GPIO 13 - Enable Pumps  */
 | 
					#define OUTPUT_ENABLE_PUMP   GPIO_NUM_13 /**< GPIO 13 - Enable Pumps  */
 | 
				
			||||||
 | 
					#ifdef HWREVISION07 
 | 
				
			||||||
 | 
					#define OUTPUT_ENABLE_SENSOR     GPIO_NUM_16 /**< GPIO 16 - Enable Sensors */
 | 
				
			||||||
 | 
					#define SENSOR_ONEWIRE      GPIO_NUM_2   /** GPIO 02 - Temperatur sensor, Battery and other cool onewire stuff */
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define OUTPUT_ENABLE_SENSOR GPIO_NUM_14 /**< GPIO 14 - Enable Sensors  */
 | 
				
			||||||
#define SENSOR_ONEWIRE      GPIO_NUM_4 /**< GPIO 12 - Temperatur sensor, Battery and other cool onewire stuff */
 | 
					#define SENSOR_ONEWIRE      GPIO_NUM_4 /**< GPIO 12 - Temperatur sensor, Battery and other cool onewire stuff */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef ANALOG_WATER
 | 
				
			||||||
 | 
					#define SENSOR_TANK_ANALOG     ANALOG_WATER /**< GPIO 34 - analog water sensor (GPIO_NUM_34) */ 
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#ifdef HWREVISION07
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
#define SENSOR_TANK_SDA     GPIO_NUM_17 /**< GPIO 17 - water sensor SDA */ 
 | 
					#define SENSOR_TANK_SDA     GPIO_NUM_17 /**< GPIO 17 - water sensor SDA */ 
 | 
				
			||||||
#define SENSOR_TANK_SCL     GPIO_NUM_16 /**< GPIO 16 - water sensor SCL */
 | 
					#define SENSOR_TANK_SCL     GPIO_NUM_16 /**< GPIO 16 - water sensor SCL */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#define BUTTON              GPIO_NUM_0  /**< GPIO 0 - Fix button of NodeMCU */
 | 
					#define BUTTON              GPIO_NUM_0  /**< GPIO 0 - Fix button of NodeMCU */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CUSTOM1_PIN1        GPIO_NUM_34   /** direct gpio */
 | 
					#define CUSTOM1_PIN1        GPIO_NUM_34   /** direct gpio */
 | 
				
			||||||
#define CUSTOM1_PIN3        GPIO_NUM_35   /** direct gpio */
 | 
					#define CUSTOM1_PIN3        GPIO_NUM_35   /** direct gpio */
 | 
				
			||||||
 | 
					#ifdef HWREVISION07
 | 
				
			||||||
 | 
					#define CUSTOM1_PIN5        GPIO_NUM_4   /** mosfet controlled */
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
#define CUSTOM1_PIN5        GPIO_NUM_2   /** mosfet controlled */
 | 
					#define CUSTOM1_PIN5        GPIO_NUM_2   /** mosfet controlled */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#define CUSTOM1_PIN7        GPIO_NUM_12   /** mosfet controlled */
 | 
					#define CUSTOM1_PIN7        GPIO_NUM_12   /** mosfet controlled */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* @} */
 | 
					/* @} */
 | 
				
			||||||
@@ -85,18 +111,29 @@
 | 
				
			|||||||
    #define FLOWMETER_PULSES_PER_ML 2.2
 | 
					    #define FLOWMETER_PULSES_PER_ML 2.2
 | 
				
			||||||
    #define FIRMWARE_FEATURE1   "Flow"
 | 
					    #define FIRMWARE_FEATURE1   "Flow"
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					    #ifdef ANALOG_WATER
 | 
				
			||||||
 | 
					    #define FIRMWARE_FEATURE1   "Water"
 | 
				
			||||||
 | 
					    #else
 | 
				
			||||||
    #define FIRMWARE_FEATURE1   ""
 | 
					    #define FIRMWARE_FEATURE1   ""
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef TIMED_LIGHT_PIN
 | 
					#ifdef TIMED_LIGHT_PIN
 | 
				
			||||||
    #define FIRMWARE_FEATURE2   "Light"
 | 
					    #define FIRMWARE_FEATURE2   "Light"
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    #define FIRMWARE_FEATURE2   ""
 | 
					        #define FIRMWARE_FEATURE2   ""
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FIRMWARE_BASENAME "PlantControl"
 | 
					#define FIRMWARE_BASENAME "PlantControl"
 | 
				
			||||||
#define FIRMWARE_NAME FIRMWARE_BASENAME FIRMWARE_FEATURE1 FIRMWARE_FEATURE2
 | 
					#define FIRMWARE_NAME FIRMWARE_BASENAME FIRMWARE_FEATURE1 FIRMWARE_FEATURE2
 | 
				
			||||||
#define FIRMWARE_VERSION "3.01 HW0.10b" 
 | 
					#define FIRMWARE_VERSIONNMUMBER "3.021"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HWREVISION07
 | 
				
			||||||
 | 
					    #define FIRMWARE_VERSION FIRMWARE_VERSIONNMUMBER " HW0.7"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    #define FIRMWARE_VERSION FIRMWARE_VERSIONNMUMBER " HW0.10b"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MOIST_SENSOR_MAX_FRQ               5200 // 60kHz (500Hz margin)
 | 
					#define MOIST_SENSOR_MAX_FRQ               5200 // 60kHz (500Hz margin)
 | 
				
			||||||
#define MOIST_SENSOR_MIN_FRQ                500 // 0.5kHz (500Hz margin)
 | 
					#define MOIST_SENSOR_MIN_FRQ                500 // 0.5kHz (500Hz margin)
 | 
				
			||||||
@@ -104,28 +141,36 @@
 | 
				
			|||||||
#define ANALOG_SENSOR_MAX_MV                1300 //successive approximation of good range
 | 
					#define ANALOG_SENSOR_MAX_MV                1300 //successive approximation of good range
 | 
				
			||||||
#define ANALOG_SENSOR_MIN_MV                100  //successive approximation of good range
 | 
					#define ANALOG_SENSOR_MIN_MV                100  //successive approximation of good range
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SOLAR_VOLT_FACTOR           11
 | 
					#ifdef HWREVISION07
 | 
				
			||||||
 | 
					#define SOLAR_VOLT_FACTOR           (4.0306f) /**< 100k and 33k voltage dividor */
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define SOLAR_VOLT_FACTOR           (11.0f) /**< Configuratiion before dd3888ba52f51338788820a933c0a6f4bee78ed5 */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#define BATTSENSOR_INDEX_SOLAR      0
 | 
					#define BATTSENSOR_INDEX_SOLAR      0
 | 
				
			||||||
#define BATTSENSOR_INDEX_BATTERY    1
 | 
					#define BATTSENSOR_INDEX_BATTERY    1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MQTT_TIMEOUT                (1000 * 60) /**< After 10 seconds, MQTT is expected to be connected */
 | 
					#define MQTT_TIMEOUT                (1000 * 60) /**< After 10 seconds, MQTT is expected to be connected */
 | 
				
			||||||
#define ESP_STALE_TIMEOUT           (MQTT_TIMEOUT+(700*1000))
 | 
					#define ESP_STALE_TIMEOUT           (MQTT_TIMEOUT+(700*1000))
 | 
				
			||||||
 | 
					#define ESP_ADC_MAX                 4095
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_PLANTS          7
 | 
					#define MAX_PLANTS          7
 | 
				
			||||||
#define SOLAR_CHARGE_MIN_VOLTAGE    7   /**< Sun is rising (morning detected) */
 | 
					#define SOLAR_CHARGE_MIN_VOLTAGE    7   /**< Sun is rising (morning detected) */
 | 
				
			||||||
#define SOLAR_CHARGE_MAX_VOLTAGE    9   /**< Sun is shining (noon)  */
 | 
					#define SOLAR_CHARGE_MAX_VOLTAGE    9   /**< Sun is shining (noon)  */
 | 
				
			||||||
#define SOLAR_MAX_VOLTAGE_POSSIBLE  100 /**< higher values are treated as not connected sensor  */
 | 
					#define SOLAR_MAX_VOLTAGE_POSSIBLE  100 /**< higher values are treated as not connected sensor  */
 | 
				
			||||||
#define VOLT_MAX_BATT               4.2f
 | 
					#define VOLT_MAX_BATT               4.2f
 | 
				
			||||||
#define VOLT_MIN_BATT               3.0f    /**< Minimum battery voltage for normal operation */
 | 
					#define VOLT_SENSORS_BATT           3.6f    /**< Minimum battery voltage for sensor (and pump) usage */
 | 
				
			||||||
#define LOWVOLT_SLEEP_FACTOR        3       /**< Factor for nightsleep delay, if the battery drops below minimum (@see VOLT_MIN_BATT) */
 | 
					#define VOLT_MIN_BATT               3.4f    /**< Minimum battery voltage for normal operation */
 | 
				
			||||||
#define LOWVOLT_SLEEP_MINIMUM       1800    /**< At low voltage sleep at least for 30 minutes */
 | 
					#define LOWVOLT_SLEEP_FACTOR        6       /**< Factor for nightsleep delay, if the battery drops below minimum (@see VOLT_MIN_BATT) */
 | 
				
			||||||
 | 
					#define LOWVOLT_SLEEP_MINIMUM       7200    /**< At low voltage sleep at least for 120 minutes (two hours) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WATER_LEVEL_MINIMUM         500      /**< Minimum Analog value (1023 is the maximum)*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_CONFIG_SETTING_ITEMS 100 /**< Parameter, that can be configured in Homie */
 | 
					#define MAX_CONFIG_SETTING_ITEMS 100 /**< Parameter, that can be configured in Homie */
 | 
				
			||||||
#define MAX_JSON_CONFIG_FILE_SIZE_CUSTOM 2500
 | 
					#define MAX_JSON_CONFIG_FILE_SIZE_CUSTOM 2500
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TEMPERATUR_TIMEOUT              3000    /**< 3 Seconds timeout for the temperatures sensors */
 | 
					#define TEMPERATUR_TIMEOUT              5000    /**< 5 Seconds timeout for the temperatures sensors */
 | 
				
			||||||
#define WATERSENSOR_TIMEOUT             3000    /**< 3 Seconds timeout for the water distance sensor */
 | 
					#define WATERSENSOR_TIMEOUT             1000    /**< 1 Seconds timeout for the water distance sensor */
 | 
				
			||||||
#define WATERSENSOR_CYCLE               10       /**< 5 sensor measurement are performed */
 | 
					#define WATERSENSOR_CYCLE               10      /**< 10 sensor measurement are performed */
 | 
				
			||||||
#define DS18B20_RESOLUTION              9       /**< 9bit temperature resolution -> 0.5°C steps */
 | 
					#define DS18B20_RESOLUTION              9       /**< 9bit temperature resolution -> 0.5°C steps */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define UTC_OFFSET_DE                   3600    /* UTC offset in seconds for Germany */
 | 
					#define UTC_OFFSET_DE                   3600    /* UTC offset in seconds for Germany */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,9 +75,6 @@ HomieNode stayAlive("stay", "alive", "alive");  /**< Necessary for Mqtt Active C
 | 
				
			|||||||
HomieSetting<long> deepSleepTime("sleep", "time in seconds to sleep");
 | 
					HomieSetting<long> deepSleepTime("sleep", "time in seconds to sleep");
 | 
				
			||||||
HomieSetting<long> deepSleepNightTime("nightsleep", "time in seconds to sleep (0 uses same setting: deepsleep at night, too)");
 | 
					HomieSetting<long> deepSleepNightTime("nightsleep", "time in seconds to sleep (0 uses same setting: deepsleep at night, too)");
 | 
				
			||||||
HomieSetting<long> pumpIneffectiveWarning("pumpConsecutiveWarn", "if the pump was triggered this amount directly after each cooldown, without resolving dryness, warn");
 | 
					HomieSetting<long> pumpIneffectiveWarning("pumpConsecutiveWarn", "if the pump was triggered this amount directly after each cooldown, without resolving dryness, warn");
 | 
				
			||||||
HomieSetting<long> waterLevelMax("tankmax", "distance (mm) at maximum water level");
 | 
					 | 
				
			||||||
HomieSetting<long> waterLevelMin("tankmin", "distance (mm) at minimum water level (pumps still covered)");
 | 
					 | 
				
			||||||
HomieSetting<long> waterLevelWarn("tankwarn", "warn (mm) if below this water level %");
 | 
					 | 
				
			||||||
HomieSetting<long> waterLevelVol("tankVolume", "(ml) between minimum and maximum");
 | 
					HomieSetting<long> waterLevelVol("tankVolume", "(ml) between minimum and maximum");
 | 
				
			||||||
HomieSetting<const char *> lipoSensorAddr("lipoDSAddr", "1wire address for lipo temperature sensor");
 | 
					HomieSetting<const char *> lipoSensorAddr("lipoDSAddr", "1wire address for lipo temperature sensor");
 | 
				
			||||||
HomieSetting<const char *> waterSensorAddr("tankDSAddr", "1wire address for water temperature sensor");
 | 
					HomieSetting<const char *> waterSensorAddr("tankDSAddr", "1wire address for water temperature sensor");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,8 @@
 | 
				
			|||||||
#define LOG_SENSORMODE_UNKNOWN "Unknown sensor mode requested"
 | 
					#define LOG_SENSORMODE_UNKNOWN "Unknown sensor mode requested"
 | 
				
			||||||
#define LOG_SENSORMODE_UNKNOWN_CODE -5
 | 
					#define LOG_SENSORMODE_UNKNOWN_CODE -5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LOG_SENSOR_MISSING -6
 | 
					#define LOG_SENSOR_MISSING_ERROR_MESSAGE "1Wire: sensors found"
 | 
				
			||||||
 | 
					#define LOG_SENSOR_MISSING_ERROR_CODE -6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LOG_PUMP_AND_DOWNLOADMODE "Download mode, ignoring pump request"
 | 
					#define LOG_PUMP_AND_DOWNLOADMODE "Download mode, ignoring pump request"
 | 
				
			||||||
#define LOG_PUMP_AND_DOWNLOADMODE_CODE 2
 | 
					#define LOG_PUMP_AND_DOWNLOADMODE_CODE 2
 | 
				
			||||||
@@ -46,5 +47,10 @@
 | 
				
			|||||||
#define LOG_SLEEP_CYCLE 102
 | 
					#define LOG_SLEEP_CYCLE 102
 | 
				
			||||||
#define LOG_MISSING_PUMP -4
 | 
					#define LOG_MISSING_PUMP -4
 | 
				
			||||||
#define LOG_BOOT_ERROR_DETECTION 10000
 | 
					#define LOG_BOOT_ERROR_DETECTION 10000
 | 
				
			||||||
 | 
					#define LOG_BOOT_ERROR_IMG_UNDEFINED        (LOG_BOOT_ERROR_DETECTION + 1)
 | 
				
			||||||
 | 
					#define LOG_BOOT_ERROR_IMG_NEW              (LOG_BOOT_ERROR_DETECTION + 2)
 | 
				
			||||||
 | 
					#define LOG_BOOT_ERROR_IMG_INVALID          (LOG_BOOT_ERROR_DETECTION + 3)
 | 
				
			||||||
 | 
					#define LOG_BOOT_ERROR_IMG_VALID            (LOG_BOOT_ERROR_DETECTION + 4)
 | 
				
			||||||
 | 
					#define LOG_BOOT_ERROR_IMG_PENDING_VERIFY   (LOG_BOOT_ERROR_DETECTION + 5)
 | 
				
			||||||
#define LOG_SOLAR_CHARGER_MISSING 300
 | 
					#define LOG_SOLAR_CHARGER_MISSING 300
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,9 @@ build_flags = -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
 | 
				
			|||||||
    -DPLANT6_SENSORTYPE=FREQUENCY_MOD_RESISTANCE_PROBE
 | 
					    -DPLANT6_SENSORTYPE=FREQUENCY_MOD_RESISTANCE_PROBE
 | 
				
			||||||
    -DTIMED_LIGHT_PIN=CUSTOM1_PIN5
 | 
					    -DTIMED_LIGHT_PIN=CUSTOM1_PIN5
 | 
				
			||||||
    -DFLOWMETER_PIN=CUSTOM1_PIN1
 | 
					    -DFLOWMETER_PIN=CUSTOM1_PIN1
 | 
				
			||||||
 | 
					    -DANALOG_WATER=GPIO_NUM_34
 | 
				
			||||||
 | 
					    ; Optional: Compatibilitymode for hardware revision 0.7
 | 
				
			||||||
 | 
					    ;-DHWREVISION07=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
board_build.partitions = defaultWithSmallerSpiffs.csv
 | 
					board_build.partitions = defaultWithSmallerSpiffs.csv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,8 +54,10 @@ void Plant::init(void)
 | 
				
			|||||||
                                                  { return ((candidate >= 0) && (candidate <= 100)); });
 | 
					                                                  { return ((candidate >= 0) && (candidate <= 100)); });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Initialize Hardware */
 | 
					    /* Initialize Hardware */
 | 
				
			||||||
 | 
					    pinMode(this->mPinPump, OUTPUT);
 | 
				
			||||||
 | 
					    digitalWrite(this->mPinPump, LOW);
 | 
				
			||||||
    ledcSetup(this->mPlantId, PWM_FREQ, PWM_BITS);
 | 
					    ledcSetup(this->mPlantId, PWM_FREQ, PWM_BITS);
 | 
				
			||||||
    ledcAttachPin(mPinPump, this->mPlantId);
 | 
					    ledcAttachPin(this->mPinPump, this->mPlantId);
 | 
				
			||||||
    ledcWrite(this->mPlantId, 0);
 | 
					    ledcWrite(this->mPlantId, 0);
 | 
				
			||||||
    pinMode(this->mPinSensor, INPUT);
 | 
					    pinMode(this->mPinSensor, INPUT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,7 +51,10 @@ extern "C" bool verifyRollbackLater(){
 | 
				
			|||||||
 *                                     DEFINES
 | 
					 *                                     DEFINES
 | 
				
			||||||
 ******************************************************************************/
 | 
					 ******************************************************************************/
 | 
				
			||||||
#define AMOUNT_SENOR_QUERYS 8
 | 
					#define AMOUNT_SENOR_QUERYS 8
 | 
				
			||||||
 | 
					#ifdef ANALOG_WATER
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
#define MAX_TANK_DEPTH 5000
 | 
					#define MAX_TANK_DEPTH 5000
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#define REBOOT_LOOP_DETECTION_ERROR 5
 | 
					#define REBOOT_LOOP_DETECTION_ERROR 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/******************************************************************************
 | 
					/******************************************************************************
 | 
				
			||||||
@@ -77,9 +80,9 @@ RTC_DATA_ATTR long consecutiveWateringPlant[MAX_PLANTS] = {0};
 | 
				
			|||||||
/******************************************************************************
 | 
					/******************************************************************************
 | 
				
			||||||
 *                            LOCAL VARIABLES
 | 
					 *                            LOCAL VARIABLES
 | 
				
			||||||
 ******************************************************************************/
 | 
					 ******************************************************************************/
 | 
				
			||||||
bool volatile mDownloadMode = false; /**< Controller must not sleep */
 | 
					bool volatile vmDownloadMode = false; /**< Controller must not sleep */
 | 
				
			||||||
bool volatile mSensorsRead = false;  /**< Sensors are read without Wifi or MQTT */
 | 
					bool volatile vmSensorsRead = false;  /**< Sensors are read without Wifi or MQTT */
 | 
				
			||||||
int volatile pumpToRun = -1;         /** pump to run  at the end of the cycle */
 | 
					int volatile vmPumpToRun = -1;         /** pump to run  at the end of the cycle */
 | 
				
			||||||
int volatile selfTestPumpRun = -1;   /** pump to run  at the end of the cycle */
 | 
					int volatile selfTestPumpRun = -1;   /** pump to run  at the end of the cycle */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool mConfigured = false;
 | 
					bool mConfigured = false;
 | 
				
			||||||
@@ -148,23 +151,23 @@ void finsihedCycleSucessfully()
 | 
				
			|||||||
  esp_ota_img_states_t ota_state;
 | 
					  esp_ota_img_states_t ota_state;
 | 
				
			||||||
  if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK)
 | 
					  if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    log(LOG_LEVEL_INFO, "Get State Partition was Successfull", LOG_BOOT_ERROR_DETECTION); 
 | 
					    log(LOG_LEVEL_DEBUG, "Get State Partition was Successfull", LOG_BOOT_ERROR_DETECTION); 
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if(ota_state == ESP_OTA_IMG_UNDEFINED){
 | 
					    if(ota_state == ESP_OTA_IMG_UNDEFINED){
 | 
				
			||||||
      log(LOG_LEVEL_INFO, "ESP_OTA_IMG_UNDEFINED should not happen with rollback", LOG_BOOT_ERROR_DETECTION);
 | 
					      log(LOG_LEVEL_DEBUG, "ESP_OTA_IMG_UNDEFINED should not happen with rollback", LOG_BOOT_ERROR_IMG_UNDEFINED);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(ota_state == ESP_OTA_IMG_NEW){
 | 
					    if(ota_state == ESP_OTA_IMG_NEW){
 | 
				
			||||||
      log(LOG_LEVEL_INFO, "ESP_OTA_IMG_NEW", LOG_BOOT_ERROR_DETECTION);
 | 
					      log(LOG_LEVEL_DEBUG, "ESP_OTA_IMG_NEW", LOG_BOOT_ERROR_IMG_NEW);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(ota_state == ESP_OTA_IMG_INVALID){
 | 
					    if(ota_state == ESP_OTA_IMG_INVALID){
 | 
				
			||||||
      log(LOG_LEVEL_INFO, "ESP_OTA_IMG_INVALID", LOG_BOOT_ERROR_DETECTION);
 | 
					      log(LOG_LEVEL_DEBUG, "ESP_OTA_IMG_INVALID", LOG_BOOT_ERROR_IMG_INVALID);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(ota_state == ESP_OTA_IMG_VALID){
 | 
					    if(ota_state == ESP_OTA_IMG_VALID){
 | 
				
			||||||
      log(LOG_LEVEL_INFO, "ESP_OTA_IMG_VALID", LOG_BOOT_ERROR_DETECTION);
 | 
					      log(LOG_LEVEL_DEBUG, "ESP_OTA_IMG_VALID", LOG_BOOT_ERROR_IMG_VALID);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (ota_state == ESP_OTA_IMG_PENDING_VERIFY)
 | 
					    if (ota_state == ESP_OTA_IMG_PENDING_VERIFY)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      log(LOG_LEVEL_INFO, "ESP_OTA_IMG_PENDING_VERIFY Diagnostics completed successfully! Marking as valid", LOG_BOOT_ERROR_DETECTION);
 | 
					      log(LOG_LEVEL_DEBUG, "ESP_OTA_IMG_PENDING_VERIFY Diagnostics completed successfully! Marking as valid", LOG_BOOT_ERROR_IMG_PENDING_VERIFY);
 | 
				
			||||||
      esp_ota_mark_app_valid_cancel_rollback();
 | 
					      esp_ota_mark_app_valid_cancel_rollback();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -172,11 +175,11 @@ void finsihedCycleSucessfully()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void espDeepSleep(bool afterPump = false)
 | 
					void espDeepSleep(bool afterPump = false)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (mDownloadMode)
 | 
					  /* download mode or normal operation should restore device status*/
 | 
				
			||||||
 | 
					  finsihedCycleSucessfully();
 | 
				
			||||||
 | 
					  if (vmDownloadMode)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    log(LOG_LEVEL_DEBUG, "abort deepsleep, DownloadMode active", LOG_DEBUG_CODE);
 | 
					    log(LOG_LEVEL_DEBUG, "abort deepsleep, DownloadMode active", LOG_DEBUG_CODE);
 | 
				
			||||||
    // if we manage to get to the download mode, the device can be restored
 | 
					 | 
				
			||||||
    finsihedCycleSucessfully();
 | 
					 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (aliveWasRead())
 | 
					  if (aliveWasRead())
 | 
				
			||||||
@@ -201,7 +204,7 @@ void espDeepSleep(bool afterPump = false)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
 | 
					  esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  long secondsToSleep = -1;
 | 
					  unsigned long secondsToSleep = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (afterPump)
 | 
					  if (afterPump)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
@@ -210,9 +213,8 @@ void espDeepSleep(bool afterPump = false)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    if (mBatteryVoltage < VOLT_MIN_BATT) 
 | 
					    if ( ((int) (mBatteryVoltage * 100)) < ((int) (VOLT_MIN_BATT * 100)) )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      log(LOG_LEVEL_INFO, String(String(mBatteryVoltage) + "V! Almost empty -> deepSleepNight " + String(LOWVOLT_SLEEP_FACTOR)) + " times", LOG_SLEEP_LOWVOLTAGE);
 | 
					 | 
				
			||||||
      /* use the largest sleeping duration */
 | 
					      /* use the largest sleeping duration */
 | 
				
			||||||
      if (deepSleepNightTime.get() > deepSleepTime.get()) {
 | 
					      if (deepSleepNightTime.get() > deepSleepTime.get()) {
 | 
				
			||||||
        secondsToSleep = (deepSleepNightTime.get() * LOWVOLT_SLEEP_FACTOR);
 | 
					        secondsToSleep = (deepSleepNightTime.get() * LOWVOLT_SLEEP_FACTOR);
 | 
				
			||||||
@@ -223,6 +225,7 @@ void espDeepSleep(bool afterPump = false)
 | 
				
			|||||||
      if (secondsToSleep < LOWVOLT_SLEEP_MINIMUM) {
 | 
					      if (secondsToSleep < LOWVOLT_SLEEP_MINIMUM) {
 | 
				
			||||||
        secondsToSleep = LOWVOLT_SLEEP_MINIMUM;
 | 
					        secondsToSleep = LOWVOLT_SLEEP_MINIMUM;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      log(LOG_LEVEL_INFO, String(String(mBatteryVoltage) + "V! Almost empty -> deepSleepNight " + String(LOWVOLT_SLEEP_FACTOR)) + " times (" + secondsToSleep + "s)", LOG_SLEEP_LOWVOLTAGE);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (mSolarVoltage < SOLAR_CHARGE_MIN_VOLTAGE)
 | 
					    else if (mSolarVoltage < SOLAR_CHARGE_MIN_VOLTAGE)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -236,12 +239,14 @@ void espDeepSleep(bool afterPump = false)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  finsihedCycleSucessfully();
 | 
					  #define SECOND2USECOND_FACTOR (1000U * 1000U)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* sleep always at least one second */
 | 
					  /* sleep always at least one second */
 | 
				
			||||||
  if (secondsToSleep < 0) {
 | 
					  if (secondsToSleep <= 0) {
 | 
				
			||||||
    secondsToSleep = 1;
 | 
					    secondsToSleep = (unsigned long) (UINT64_MAX / SECOND2USECOND_FACTOR);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  esp_sleep_enable_timer_wakeup((secondsToSleep * 1000U * 1000U));
 | 
					  esp_sleep_enable_timer_wakeup((secondsToSleep * SECOND2USECOND_FACTOR));
 | 
				
			||||||
 | 
					  #undef SECOND2USECOND_FACTOR
 | 
				
			||||||
  if (aliveWasRead())
 | 
					  if (aliveWasRead())
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    delay(1000);
 | 
					    delay(1000);
 | 
				
			||||||
@@ -354,68 +359,35 @@ void readPowerSwitchedSensors()
 | 
				
			|||||||
    Plant plant = mPlants[i];
 | 
					    Plant plant = mPlants[i];
 | 
				
			||||||
    switch (plant.getSensorMode())
 | 
					    switch (plant.getSensorMode())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      case FREQUENCY_MOD_RESISTANCE_PROBE: {
 | 
					      case FREQUENCY_MOD_RESISTANCE_PROBE:
 | 
				
			||||||
        Serial << "Plant " << i << " measurement: " << mPlants[i].getCurrentMoistureRaw() << " hz " << mPlants[i].getCurrentMoisturePCT() << "%" <<  endl;
 | 
					        Serial << "Plant " << i << " measurement: " << mPlants[i].getCurrentMoistureRaw() << " hz " << mPlants[i].getCurrentMoisturePCT() << "%" <<  endl;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      case ANALOG_RESISTANCE_PROBE :
 | 
				
			||||||
      case ANALOG_RESISTANCE_PROBE : {
 | 
					 | 
				
			||||||
        Serial << "Plant " << i << " measurement: " << mPlants[i].getCurrentMoistureRaw() << " mV " << mPlants[i].getCurrentMoisturePCT() << "%" <<  endl;
 | 
					        Serial << "Plant " << i << " measurement: " << mPlants[i].getCurrentMoistureRaw() << " mV " << mPlants[i].getCurrentMoisturePCT() << "%" <<  endl;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      default:
 | 
				
			||||||
      case NONE : {
 | 
					      case NONE:
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Wire.begin(SENSOR_TANK_SDA, SENSOR_TANK_SCL);
 | 
					  #ifdef ANALOG_WATER
 | 
				
			||||||
  // Source: https://www.st.com/resource/en/datasheet/vl53l0x.pdf
 | 
					  Serial << "Analog water measurement " << WATERSENSOR_CYCLE << " cycles.." <<  endl;
 | 
				
			||||||
  tankSensor.setAddress(0x52);
 | 
					  Serial.flush();
 | 
				
			||||||
  tankSensor.setBus(&Wire);
 | 
					  
 | 
				
			||||||
  delay(50);
 | 
					  /* Read analog Water sensor*/
 | 
				
			||||||
  Serial << "Distance sensor init" << endl;
 | 
					  for(int i=0; i < WATERSENSOR_CYCLE; i++)
 | 
				
			||||||
  long start = millis();
 | 
					 | 
				
			||||||
  bool distanceReady = false;
 | 
					 | 
				
			||||||
  while ((start + WATERSENSOR_TIMEOUT) > millis())
 | 
					 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    if (tankSensor.init())
 | 
					    int value = analogRead(SENSOR_TANK_ANALOG);
 | 
				
			||||||
    {
 | 
					    Serial << "Round " << i << " measurement: " << value << " mV " <<  endl;
 | 
				
			||||||
      distanceReady = true;
 | 
					    waterRawSensor.add(value);
 | 
				
			||||||
      break;
 | 
					    delay(7);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      delay(200);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (distanceReady)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    waterRawSensor.clear();
 | 
					 | 
				
			||||||
    tankSensor.setSignalRateLimit(0.1);
 | 
					 | 
				
			||||||
    // increase laser pulse periods (defaults are 14 and 10 PCLKs)
 | 
					 | 
				
			||||||
    tankSensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
 | 
					 | 
				
			||||||
    tankSensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
 | 
					 | 
				
			||||||
    tankSensor.setMeasurementTimingBudget(200000);
 | 
					 | 
				
			||||||
    Serial << "Distance sensor measuring" << endl;
 | 
					 | 
				
			||||||
    for (int readCnt = 0; readCnt < WATERSENSOR_CYCLE; readCnt++)
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      if (!tankSensor.timeoutOccurred())
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        uint16_t distance = tankSensor.readRangeSingleMillimeters();
 | 
					 | 
				
			||||||
        if (distance < MAX_TANK_DEPTH)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          waterRawSensor.add(distance);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      delay(50);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Serial << "Distance sensor " << waterRawSensor.getMedian() << " mm" << endl;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    log(LOG_LEVEL_WARN, LOG_TANKSENSOR_FAIL_DETECT, LOG_TANKSENSOR_FAIL_DETECT_CODE);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  Serial << "Analog water measurement done" <<  endl;
 | 
				
			||||||
 | 
					  #else
 | 
				
			||||||
 | 
					  Serial << "Analog water measurement deactivated" <<  endl;
 | 
				
			||||||
 | 
					  #endif
 | 
				
			||||||
 | 
					  Serial.flush();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* deactivate the sensors */
 | 
					  /* deactivate the sensors */
 | 
				
			||||||
  digitalWrite(OUTPUT_ENABLE_SENSOR, LOW);
 | 
					  digitalWrite(OUTPUT_ENABLE_SENSOR, LOW);
 | 
				
			||||||
@@ -431,12 +403,12 @@ void onHomieEvent(const HomieEvent &event)
 | 
				
			|||||||
  case HomieEventType::SENDING_STATISTICS:
 | 
					  case HomieEventType::SENDING_STATISTICS:
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  case HomieEventType::MQTT_READY:
 | 
					  case HomieEventType::MQTT_READY:
 | 
				
			||||||
    if (mSensorsRead)
 | 
					    if (vmSensorsRead)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      Serial.printf("Timeout occured... too late!\r\n");
 | 
					      Serial.printf("Timeout occured... too late!\r\n");
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    mSensorsRead = true; // MQTT is working, deactivate timeout logic
 | 
					    vmSensorsRead = true; // MQTT is working, deactivate timeout logic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    configTime(UTC_OFFSET_DE, UTF_OFFSET_DE_DST, ntpServer.get());
 | 
					    configTime(UTC_OFFSET_DE, UTF_OFFSET_DE_DST, ntpServer.get());
 | 
				
			||||||
    startMQTTRoundtripTest();
 | 
					    startMQTTRoundtripTest();
 | 
				
			||||||
@@ -447,7 +419,7 @@ void onHomieEvent(const HomieEvent &event)
 | 
				
			|||||||
      mPlants[i].deactivatePump();
 | 
					      mPlants[i].deactivatePump();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    otaRunning = true;
 | 
					    otaRunning = true;
 | 
				
			||||||
    mDownloadMode = true;
 | 
					    vmDownloadMode = true;
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  case HomieEventType::OTA_SUCCESSFUL:
 | 
					  case HomieEventType::OTA_SUCCESSFUL:
 | 
				
			||||||
    digitalWrite(OUTPUT_ENABLE_SENSOR, LOW);
 | 
					    digitalWrite(OUTPUT_ENABLE_SENSOR, LOW);
 | 
				
			||||||
@@ -464,12 +436,21 @@ int determineNextPump(bool isLowLight)
 | 
				
			|||||||
  int pumpToUse = -1;
 | 
					  int pumpToUse = -1;
 | 
				
			||||||
  for (int i = 0; i < MAX_PLANTS; i++)
 | 
					  for (int i = 0; i < MAX_PLANTS; i++)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
 | 
					    Plant plant = mPlants[i];
 | 
				
			||||||
 | 
					    switch (plant.getSensorMode())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      case FREQUENCY_MOD_RESISTANCE_PROBE:
 | 
				
			||||||
 | 
					        log(LOG_LEVEL_DEBUG, 
 | 
				
			||||||
 | 
					              String("Plant " + String(i) + " measurement: " + String(plant.getCurrentMoistureRaw()) + " hz " + String(plant.getCurrentMoisturePCT()) + "%"),
 | 
				
			||||||
 | 
					              LOG_DEBUG_CODE);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool wateralarm = consecutiveWateringPlant[i] >= pumpIneffectiveWarning.get();
 | 
					    bool wateralarm = consecutiveWateringPlant[i] >= pumpIneffectiveWarning.get();
 | 
				
			||||||
    if (wateralarm)
 | 
					    if (wateralarm)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      log(LOG_LEVEL_ERROR, String(String(i) + " Plant still dry after " + String(consecutiveWateringPlant[i]) + " watering attempts"), LOG_PUMP_INEFFECTIVE);
 | 
					      log(LOG_LEVEL_ERROR, String(String(i) + " Plant still dry after " + String(consecutiveWateringPlant[i]) + " watering attempts"), LOG_PUMP_INEFFECTIVE);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Plant plant = mPlants[i];
 | 
					 | 
				
			||||||
    if (!plant.isPumpTriggerActive())
 | 
					    if (!plant.isPumpTriggerActive())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      plant.publishState(PLANTSTATE_NUM_DEACTIVATED, PLANTSTATE_STR_DEACTIVATED);
 | 
					      plant.publishState(PLANTSTATE_NUM_DEACTIVATED, PLANTSTATE_STR_DEACTIVATED);
 | 
				
			||||||
@@ -530,7 +511,7 @@ int determineNextPump(bool isLowLight)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          if (mDownloadMode)
 | 
					          if (vmDownloadMode)
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            plant.publishState(PLANTSTATE_NUM_ACTIVE_SUPESSED, PLANTSTATE_STR_ACTIVE_SUPESSED);
 | 
					            plant.publishState(PLANTSTATE_NUM_ACTIVE_SUPESSED, PLANTSTATE_STR_ACTIVE_SUPESSED);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
@@ -590,15 +571,15 @@ bool aliveHandler(const HomieRange &range, const String &value)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (value.equals("ON") || value.equals("On") || value.equals("1"))
 | 
					  if (value.equals("ON") || value.equals("On") || value.equals("1"))
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    mDownloadMode = true;
 | 
					    vmDownloadMode = true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    if (mDownloadMode)
 | 
					    if (vmDownloadMode)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      esp_restart();
 | 
					      esp_restart();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    mDownloadMode = false;
 | 
					    vmDownloadMode = false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
@@ -675,11 +656,11 @@ void initPumpLogic()
 | 
				
			|||||||
  pcnt_counter_resume(unit);
 | 
					  pcnt_counter_resume(unit);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
  pumpStartTime = millis();
 | 
					  pumpStartTime = millis();
 | 
				
			||||||
  pumpTarget = millis() + (mPlants[pumpToRun].getPumpDuration() * 1000);
 | 
					  pumpTarget = millis() + (mPlants[vmPumpToRun].getPumpDuration() * 1000);
 | 
				
			||||||
  #ifdef FLOWMETER_PIN
 | 
					  #ifdef FLOWMETER_PIN
 | 
				
			||||||
    log(LOG_LEVEL_INFO, "Starting pump " + String(pumpToRun) + " for " + String(mPlants[pumpToRun].getPumpDuration()) + "s or " + String(pumpTargetMl) + "ml", LOG_PUMP_STARTED_CODE);
 | 
					    log(LOG_LEVEL_INFO, "Starting pump " + String(pumpToRun) + " for " + String(mPlants[pumpToRun].getPumpDuration()) + "s or " + String(pumpTargetMl) + "ml", LOG_PUMP_STARTED_CODE);
 | 
				
			||||||
  #else
 | 
					  #else
 | 
				
			||||||
    log(LOG_LEVEL_INFO, "Starting pump " + String(pumpToRun) + " for " + String(mPlants[pumpToRun].getPumpDuration()) + "s", LOG_PUMP_STARTED_CODE);
 | 
					    log(LOG_LEVEL_INFO, "Starting pump " + String(vmPumpToRun) + " for " + String(mPlants[vmPumpToRun].getPumpDuration()) + "s", LOG_PUMP_STARTED_CODE);
 | 
				
			||||||
  #endif
 | 
					  #endif
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -689,7 +670,7 @@ void initPumpLogic()
 | 
				
			|||||||
  delay(100);
 | 
					  delay(100);
 | 
				
			||||||
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 1);
 | 
					  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mPlants[pumpToRun].activatePump();
 | 
					  mPlants[vmPumpToRun].activatePump();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pumpActiveLoop()
 | 
					void pumpActiveLoop()
 | 
				
			||||||
@@ -700,7 +681,7 @@ void pumpActiveLoop()
 | 
				
			|||||||
  {
 | 
					  {
 | 
				
			||||||
    initPumpLogic();
 | 
					    initPumpLogic();
 | 
				
			||||||
    pumpStarted = true;
 | 
					    pumpStarted = true;
 | 
				
			||||||
    rtcLastWateringPlant[pumpToRun] = getCurrentTime();
 | 
					    rtcLastWateringPlant[vmPumpToRun] = getCurrentTime();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool mqttUpdateTick = false;
 | 
					  bool mqttUpdateTick = false;
 | 
				
			||||||
@@ -742,12 +723,12 @@ void pumpActiveLoop()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (millis() > pumpTarget)
 | 
					  if (millis() > pumpTarget)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    mPlants[pumpToRun].setProperty("watertime").send(String(duration));
 | 
					    mPlants[vmPumpToRun].setProperty("watertime").send(String(duration));
 | 
				
			||||||
    targetReached = true;
 | 
					    targetReached = true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else if (mqttUpdateTick)
 | 
					  else if (mqttUpdateTick)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    mPlants[pumpToRun].setProperty("watertime").send(String(duration));
 | 
					    mPlants[vmPumpToRun].setProperty("watertime").send(String(duration));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (targetReached)
 | 
					  if (targetReached)
 | 
				
			||||||
@@ -755,11 +736,11 @@ void pumpActiveLoop()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // disable all
 | 
					    // disable all
 | 
				
			||||||
    digitalWrite(OUTPUT_ENABLE_PUMP, LOW);
 | 
					    digitalWrite(OUTPUT_ENABLE_PUMP, LOW);
 | 
				
			||||||
    mPlants[pumpToRun].deactivatePump();
 | 
					    mPlants[vmPumpToRun].deactivatePump();
 | 
				
			||||||
    // disable loop, to prevent multi processing
 | 
					    // disable loop, to prevent multi processing
 | 
				
			||||||
    pumpStarted = false;
 | 
					    pumpStarted = false;
 | 
				
			||||||
    // if runtime is larger than cooldown, else it would run continously
 | 
					    // if runtime is larger than cooldown, else it would run continously
 | 
				
			||||||
    rtcLastWateringPlant[pumpToRun] = getCurrentTime();
 | 
					    rtcLastWateringPlant[vmPumpToRun] = getCurrentTime();
 | 
				
			||||||
    espDeepSleep(true);
 | 
					    espDeepSleep(true);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -791,6 +772,11 @@ void safeSetup()
 | 
				
			|||||||
  digitalWrite(OUTPUT_ENABLE_PUMP, LOW);
 | 
					  digitalWrite(OUTPUT_ENABLE_PUMP, LOW);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinMode(OUTPUT_ENABLE_SENSOR, OUTPUT);
 | 
					  pinMode(OUTPUT_ENABLE_SENSOR, OUTPUT);
 | 
				
			||||||
 | 
					  digitalWrite(OUTPUT_ENABLE_SENSOR, LOW);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #ifdef ANALOG_WATER
 | 
				
			||||||
 | 
					  pinMode(SENSOR_TANK_ANALOG, INPUT);
 | 
				
			||||||
 | 
					  #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static_assert(HomieInternals::MAX_CONFIG_SETTING_SIZE >= MAX_CONFIG_SETTING_ITEMS, "Limits.hpp not adjusted MAX_CONFIG_SETTING_ITEMS");
 | 
					  static_assert(HomieInternals::MAX_CONFIG_SETTING_SIZE >= MAX_CONFIG_SETTING_ITEMS, "Limits.hpp not adjusted MAX_CONFIG_SETTING_ITEMS");
 | 
				
			||||||
  if (HomieInternals::MAX_CONFIG_SETTING_SIZE < MAX_CONFIG_SETTING_ITEMS)
 | 
					  if (HomieInternals::MAX_CONFIG_SETTING_SIZE < MAX_CONFIG_SETTING_ITEMS)
 | 
				
			||||||
@@ -819,9 +805,6 @@ void safeSetup()
 | 
				
			|||||||
  deepSleepNightTime.setDefaultValue(600);
 | 
					  deepSleepNightTime.setDefaultValue(600);
 | 
				
			||||||
  ntpServer.setDefaultValue("pool.ntp.org");
 | 
					  ntpServer.setDefaultValue("pool.ntp.org");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* waterLevelMax 1000    */          /* 100cm in mm */
 | 
					 | 
				
			||||||
  waterLevelMin.setDefaultValue(50);   /* 5cm in mm */
 | 
					 | 
				
			||||||
  waterLevelWarn.setDefaultValue(500); /* 50cm in mm */
 | 
					 | 
				
			||||||
  waterLevelVol.setDefaultValue(5000); /* 5l in ml */
 | 
					  waterLevelVol.setDefaultValue(5000); /* 5l in ml */
 | 
				
			||||||
  lipoSensorAddr.setDefaultValue("");
 | 
					  lipoSensorAddr.setDefaultValue("");
 | 
				
			||||||
  waterSensorAddr.setDefaultValue("");
 | 
					  waterSensorAddr.setDefaultValue("");
 | 
				
			||||||
@@ -848,24 +831,39 @@ void safeSetup()
 | 
				
			|||||||
  {
 | 
					  {
 | 
				
			||||||
    mPlants[i].initSensors();
 | 
					    mPlants[i].initSensors();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  readPowerSwitchedSensors();
 | 
					 | 
				
			||||||
  Serial << "Reading Homie Config..." << endl;
 | 
					 | 
				
			||||||
  Homie.setup();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /************************* Start One-Wire bus ***************/
 | 
					  /************************* Start One-Wire bus ***************/
 | 
				
			||||||
  int tempInitStartTime = millis();
 | 
					  int tempInitStartTime = millis();
 | 
				
			||||||
  uint8_t sensorCount = 0U;
 | 
					  uint8_t sensorCount = 0U;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Required to read the temperature at least once */
 | 
					  /* Required to read the temperature at least once */
 | 
				
			||||||
  while ((sensorCount == 0 || !battery.isFound()) && millis() < tempInitStartTime + TEMPERATUR_TIMEOUT)
 | 
					  for(int i=0;
 | 
				
			||||||
 | 
					      ((sensorCount == 0 || !battery.isFound()) && millis() < tempInitStartTime + TEMPERATUR_TIMEOUT);
 | 
				
			||||||
 | 
					      i++)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    sensors.begin();
 | 
					    sensors.begin();
 | 
				
			||||||
    battery.begin();
 | 
					    battery.begin();
 | 
				
			||||||
    sensorCount = sensors.getDS18Count();
 | 
					    sensorCount = sensors.getDS18Count();
 | 
				
			||||||
    delay(50);
 | 
					    if (i > 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      Serial << "DS18S20 count: " << sensorCount << ", battery is found: " << battery.isFound() << " ( loop: " << i << " )" << endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    delay(100);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  readOneWireSensors();
 | 
				
			||||||
 | 
					  mBatteryVoltage = battery.getVoltage(BATTSENSOR_INDEX_BATTERY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ( ((int) (mBatteryVoltage * 100)) >= ((int) (VOLT_SENSORS_BATT * 100)) )
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    /* read all sensors with additional power source */
 | 
				
			||||||
 | 
					    readPowerSwitchedSensors();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Start Homie and Wifi */
 | 
				
			||||||
 | 
					  Serial << "Reading Homie Config..." << endl;
 | 
				
			||||||
 | 
					  Homie.setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Serial << "DS18S20 count: " << sensorCount << " found in " << (millis() - tempInitStartTime) << " ms" << endl;
 | 
					  Serial << "DS18S20 count: " << sensorCount << " found in " << (millis() - tempInitStartTime) << " ms" << endl;
 | 
				
			||||||
  Serial.flush();
 | 
					  Serial.flush();
 | 
				
			||||||
  /* Measure temperature TODO idea: move this into setup */
 | 
					  /* Measure temperature TODO idea: move this into setup */
 | 
				
			||||||
@@ -874,6 +872,23 @@ void safeSetup()
 | 
				
			|||||||
    sensors.setResolution(DS18B20_RESOLUTION);
 | 
					    sensors.setResolution(DS18B20_RESOLUTION);
 | 
				
			||||||
    sensors.requestTemperatures();
 | 
					    sensors.requestTemperatures();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    Serial << "NO SENSOR FOUND! " << endl;
 | 
				
			||||||
 | 
					    Serial << "  N   N  OOO         SSSS EEEEE N   N  SSSS  OOO  RRRR        FFFFF  OOO  U   U N   N DDDD   !" << endl;
 | 
				
			||||||
 | 
					    Serial << "  NN  N O   O       S     E     NN  N S     O   O R   R       F     O   O U   U NN  N D   D  !" << endl;
 | 
				
			||||||
 | 
					    Serial << "  N N N O   O        SSS  EEEE  N N N  SSS  O   O RRRR        FFFF  O   O U   U N N N D   D  !" << endl;
 | 
				
			||||||
 | 
					    Serial << "  N  NN O   O           S E     N  NN     S O   O R  R        F     O   O U   U N  NN D   D  !" << endl;
 | 
				
			||||||
 | 
					    Serial << "  N   N  OOO        SSSS  EEEEE N   N SSSS   OOO  R   R       F      OOO   UUU  N   N DDDD   !" << endl;
 | 
				
			||||||
 | 
					                                                                              
 | 
				
			||||||
 | 
					    Serial << "" << endl;
 | 
				
			||||||
 | 
					    Serial << "" << endl;
 | 
				
			||||||
 | 
					    Serial << FIRMWARE_NAME << " " FIRMWARE_VERSIONNMUMBER << endl;
 | 
				
			||||||
 | 
					    Serial << "" << endl;
 | 
				
			||||||
 | 
					    Serial << "Is expected to run on the following board:" << endl;
 | 
				
			||||||
 | 
					    Serial << FIRMWARE_VERSION << endl;
 | 
				
			||||||
 | 
					    Serial.flush();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mConfigured = Homie.isConfigured();
 | 
					  mConfigured = Homie.isConfigured();
 | 
				
			||||||
  if (mConfigured)
 | 
					  if (mConfigured)
 | 
				
			||||||
@@ -947,7 +962,7 @@ void safeSetup()
 | 
				
			|||||||
    delay(100);
 | 
					    delay(100);
 | 
				
			||||||
    WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 1);
 | 
					    WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 1);
 | 
				
			||||||
    Serial.println("Initial Setup. Start Accesspoint...");
 | 
					    Serial.println("Initial Setup. Start Accesspoint...");
 | 
				
			||||||
    mDownloadMode = true;
 | 
					    vmDownloadMode = true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  stayAlive.advertise("alive").setName("Alive").setDatatype(NUMBER_TYPE).settable(aliveHandler);
 | 
					  stayAlive.advertise("alive").setName("Alive").setDatatype(NUMBER_TYPE).settable(aliveHandler);
 | 
				
			||||||
  setupFinishedTimestamp = millis();
 | 
					  setupFinishedTimestamp = millis();
 | 
				
			||||||
@@ -983,7 +998,7 @@ void selfTest()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (selfTestPumpRun >= 0 && selfTestPumpRun < MAX_PLANTS)
 | 
					  if (selfTestPumpRun >= 0 && selfTestPumpRun < MAX_PLANTS)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Serial << "self test mode pump deactivate " << pumpToRun << endl;
 | 
					    Serial << "self test mode pump deactivate " << vmPumpToRun << endl;
 | 
				
			||||||
    Serial.flush();
 | 
					    Serial.flush();
 | 
				
			||||||
    mPlants[selfTestPumpRun].deactivatePump();
 | 
					    mPlants[selfTestPumpRun].deactivatePump();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -1015,7 +1030,7 @@ void loop()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  Homie.loop();
 | 
					  Homie.loop();
 | 
				
			||||||
  /* Toggel Senor LED to visualize mode 3 */
 | 
					  /* Toggel Senor LED to visualize mode 3 */
 | 
				
			||||||
  if (mDownloadMode)
 | 
					  if (vmDownloadMode)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    if (nextBlink < millis())
 | 
					    if (nextBlink < millis())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -1040,9 +1055,9 @@ void loop()
 | 
				
			|||||||
  else
 | 
					  else
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    unsigned long timeSinceSetup = millis() - setupFinishedTimestamp;
 | 
					    unsigned long timeSinceSetup = millis() - setupFinishedTimestamp;
 | 
				
			||||||
    if ((timeSinceSetup > MQTT_TIMEOUT) && (!mSensorsRead))
 | 
					    if ((timeSinceSetup > MQTT_TIMEOUT) && (!vmSensorsRead))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      mSensorsRead = true;
 | 
					      vmSensorsRead = true;
 | 
				
			||||||
      /* Disable Wifi and put modem into sleep mode */
 | 
					      /* Disable Wifi and put modem into sleep mode */
 | 
				
			||||||
      WiFi.mode(WIFI_OFF);
 | 
					      WiFi.mode(WIFI_OFF);
 | 
				
			||||||
      Serial << "Wifi mode set to " << WIFI_OFF << " mqqt was no reached within " << timeSinceSetup << "ms , fallback to offline mode " << endl;
 | 
					      Serial << "Wifi mode set to " << WIFI_OFF << " mqqt was no reached within " << timeSinceSetup << "ms , fallback to offline mode " << endl;
 | 
				
			||||||
@@ -1052,14 +1067,14 @@ void loop()
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Timeout always stopping the ESP -> no endless power consumption */
 | 
					  /** Timeout always stopping the ESP -> no endless power consumption */
 | 
				
			||||||
  if (millis() > ESP_STALE_TIMEOUT && !mDownloadMode)
 | 
					  if (millis() > ESP_STALE_TIMEOUT && !vmDownloadMode)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Serial << (millis() / 1000) << "not terminated watchdog reset" << endl;
 | 
					    Serial << (millis() / 1000) << "not terminated watchdog reset" << endl;
 | 
				
			||||||
    Serial.flush();
 | 
					    Serial.flush();
 | 
				
			||||||
    esp_restart();
 | 
					    esp_restart();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pumpToRun != -1)
 | 
					  if (vmPumpToRun != -1)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    pumpActiveLoop();
 | 
					    pumpActiveLoop();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -1082,9 +1097,8 @@ void plantcontrol()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  readOneWireSensors();
 | 
					  readOneWireSensors();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Serial << "W : " << waterRawSensor.getAverage() << " mm (" << String(waterLevelMax.get() - waterRawSensor.getAverage()) << " mm left)" << endl;
 | 
					  Serial << "W : " << waterRawSensor.getAverage() << " mm " << endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mBatteryVoltage = battery.getVoltage(BATTSENSOR_INDEX_BATTERY);
 | 
					 | 
				
			||||||
  float chipTemp = battery.getTemperature();
 | 
					  float chipTemp = battery.getTemperature();
 | 
				
			||||||
  Serial << "Chip Temperatur " << chipTemp << " °C " << endl;
 | 
					  Serial << "Chip Temperatur " << chipTemp << " °C " << endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1093,34 +1107,58 @@ void plantcontrol()
 | 
				
			|||||||
    /* Publish water values, if available */
 | 
					    /* Publish water values, if available */
 | 
				
			||||||
    if (waterRawSensor.getCount() > 0)
 | 
					    if (waterRawSensor.getCount() > 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      float remaining = (waterLevelMax.get() - waterRawSensor.getAverage());
 | 
					 | 
				
			||||||
      float actualDifference = waterLevelMax.get() - waterLevelMin.get();
 | 
					 | 
				
			||||||
      float ratio = remaining/actualDifference;
 | 
					 | 
				
			||||||
      sensorWater.setProperty("useable").send(String(actualDifference));
 | 
					 | 
				
			||||||
      if (!isnan(remaining))
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        /* measuring the distance from top -> smaller value means more water: */
 | 
					 | 
				
			||||||
        sensorWater.setProperty("remaining").send(String(ratio*100));
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (!isnan(waterRawSensor.getAverage()))
 | 
					      if (!isnan(waterRawSensor.getAverage()))
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        sensorWater.setProperty("distance").send(String(waterRawSensor.getAverage()));
 | 
					        /* measuring the distance from top -> smaller value means more water: */
 | 
				
			||||||
 | 
					        long averageWater = waterRawSensor.getAverage();
 | 
				
			||||||
 | 
					        if (averageWater < ESP_ADC_MAX) {
 | 
				
			||||||
 | 
					          long percentage = (averageWater * averageWater);
 | 
				
			||||||
 | 
					          percentage = percentage / 570000;
 | 
				
			||||||
 | 
					          /* Add offset */
 | 
				
			||||||
 | 
					          if (percentage > 0)
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            percentage += 4;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          sensorWater.setProperty("remaining").send(String(percentage));
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          sensorWater.setProperty("remaining").send(String("100"));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sensorWater.setProperty("raw").send(String(waterRawSensor.getAverage()));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    sensorLipo.setProperty("percent").send(String(100 * mBatteryVoltage / VOLT_MAX_BATT));
 | 
					    
 | 
				
			||||||
    sensorLipo.setProperty("volt").send(String(mBatteryVoltage));
 | 
					    if ( ((int) (mBatteryVoltage * 100)) < ((int) (VOLT_MIN_BATT * 100)) )
 | 
				
			||||||
    sensorLipo.setProperty("current").send(String(battery.getCurrent()));
 | 
					    {
 | 
				
			||||||
    sensorLipo.setProperty("Ah").send(String(battery.getAh()));
 | 
					      sensorLipo.setProperty("percent").send("0");
 | 
				
			||||||
    sensorLipo.setProperty("ICA").send(String(battery.getICA()));
 | 
					 | 
				
			||||||
    sensorLipo.setProperty("DCA").send(String(battery.getDCA()));
 | 
					 | 
				
			||||||
    sensorLipo.setProperty("CCA").send(String(battery.getCCA()));
 | 
					 | 
				
			||||||
    if (mSolarVoltage < SOLAR_MAX_VOLTAGE_POSSIBLE) {
 | 
					 | 
				
			||||||
      sensorSolar.setProperty("volt").send(String(mSolarVoltage));
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      log(LOG_LEVEL_INFO, String("Ignore unrealistc sun voltage" + String(mSolarVoltage) +"V"), LOG_SOLAR_CHARGER_MISSING);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    sensorTemp.setProperty(TEMPERATUR_SENSOR_CHIP).send(String(chipTemp));
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      sensorLipo.setProperty("percent").send(String(100 * (((mBatteryVoltage - VOLT_MIN_BATT) / (VOLT_MAX_BATT - VOLT_MIN_BATT)))));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (battery.isFound()) {
 | 
				
			||||||
 | 
					      sensorLipo.setProperty("volt").send(String(mBatteryVoltage));
 | 
				
			||||||
 | 
					      sensorLipo.setProperty("current").send(String(battery.getCurrent()));
 | 
				
			||||||
 | 
					      sensorLipo.setProperty("Ah").send(String(battery.getAh()));
 | 
				
			||||||
 | 
					      sensorLipo.setProperty("ICA").send(String(battery.getICA()));
 | 
				
			||||||
 | 
					      sensorLipo.setProperty("DCA").send(String(battery.getDCA()));
 | 
				
			||||||
 | 
					      sensorLipo.setProperty("CCA").send(String(battery.getCCA()));
 | 
				
			||||||
 | 
					      if (mSolarVoltage < SOLAR_MAX_VOLTAGE_POSSIBLE) {
 | 
				
			||||||
 | 
					        sensorSolar.setProperty("volt").send(String(mSolarVoltage));
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        log(LOG_LEVEL_INFO, String("Ignore unrealistc sun voltage" + String(mSolarVoltage) +"V"), LOG_SOLAR_CHARGER_MISSING);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      sensorTemp.setProperty(TEMPERATUR_SENSOR_CHIP).send(String(chipTemp));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      log(LOG_LEVEL_ERROR, String("No battery or sun sensor found"), LOG_SOLAR_CHARGER_MISSING);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Publish 1-wire sensor status on failure */
 | 
				
			||||||
 | 
					    if (sensors.getDS18Count() <= 1) {
 | 
				
			||||||
 | 
					      log(LOG_LEVEL_ERROR, String("Found " + String(sensors.getDS18Count()) + " DS18B20 sensors"), LOG_SENSOR_MISSING_ERROR_CODE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
@@ -1128,7 +1166,7 @@ void plantcontrol()
 | 
				
			|||||||
    Serial.flush();
 | 
					    Serial.flush();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool isLowLight = (mSolarVoltage <= SOLAR_CHARGE_MAX_VOLTAGE);
 | 
					bool isLowLight = (mSolarVoltage <= SOLAR_CHARGE_MIN_VOLTAGE);
 | 
				
			||||||
#if defined(TIMED_LIGHT_PIN)
 | 
					#if defined(TIMED_LIGHT_PIN)
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  bool shouldLight = determineTimedLightState(isLowLight);
 | 
					  bool shouldLight = determineTimedLightState(isLowLight);
 | 
				
			||||||
@@ -1140,30 +1178,30 @@ bool isLowLight = (mSolarVoltage <= SOLAR_CHARGE_MAX_VOLTAGE);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#endif // TIMED_LIGHT_PIN
 | 
					#endif // TIMED_LIGHT_PIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool isLiquid = waterTemp > 5;
 | 
					  bool isLiquid = (waterTemp > 5.0f);
 | 
				
			||||||
  bool hasWater = true; // By default activate the pump
 | 
					  bool hasWater = true; // By default activate the pump
 | 
				
			||||||
  if (waterRawSensor.getCount() > 0)
 | 
					  if (waterRawSensor.getCount() > 0)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    //surface of water is still nearer the sensor than required to cover the pumps
 | 
					    //surface of water is still nearer the sensor than required to cover the pumps
 | 
				
			||||||
    hasWater = waterRawSensor.getAverage() < waterLevelMin.get();
 | 
					    hasWater = waterRawSensor.getAverage() > WATER_LEVEL_MINIMUM;
 | 
				
			||||||
    if (waterRawSensor.getAverage() > waterLevelMax.get()) {
 | 
					  }
 | 
				
			||||||
      log(LOG_LEVEL_ERROR, LOG_PUMP_FULLTANK_MESSAGE, LOG_PUMP_FULLTANK_CODE);
 | 
					
 | 
				
			||||||
      hasWater = true;
 | 
					  if (mBatteryVoltage >= VOLT_SENSORS_BATT)
 | 
				
			||||||
    }
 | 
					  {
 | 
				
			||||||
 | 
					    // FIXME no water warning message
 | 
				
			||||||
 | 
					    vmPumpToRun = determineNextPump(isLowLight);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // FIXME no water warning message
 | 
					 | 
				
			||||||
  pumpToRun = determineNextPump(isLowLight);
 | 
					 | 
				
			||||||
  // early aborts
 | 
					  // early aborts
 | 
				
			||||||
  if (pumpToRun != -1)
 | 
					  if (vmPumpToRun != -1)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    if(isLiquid){
 | 
					    if(isLiquid){
 | 
				
			||||||
      if (hasWater)
 | 
					      if (hasWater)
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        if (mDownloadMode)
 | 
					        if (vmDownloadMode)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          log(LOG_LEVEL_INFO, LOG_PUMP_AND_DOWNLOADMODE, LOG_PUMP_AND_DOWNLOADMODE_CODE);
 | 
					          log(LOG_LEVEL_INFO, LOG_PUMP_AND_DOWNLOADMODE, LOG_PUMP_AND_DOWNLOADMODE_CODE);
 | 
				
			||||||
          pumpToRun = -1;
 | 
					          vmPumpToRun = -1;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          /* Pump can be used :) */
 | 
					          /* Pump can be used :) */
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -1171,18 +1209,18 @@ bool isLowLight = (mSolarVoltage <= SOLAR_CHARGE_MAX_VOLTAGE);
 | 
				
			|||||||
      else
 | 
					      else
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        log(LOG_LEVEL_ERROR, LOG_PUMP_BUTNOTANK_MESSAGE, LOG_PUMP_BUTNOTANK_CODE);
 | 
					        log(LOG_LEVEL_ERROR, LOG_PUMP_BUTNOTANK_MESSAGE, LOG_PUMP_BUTNOTANK_CODE);
 | 
				
			||||||
        pumpToRun = -1;
 | 
					        vmPumpToRun = -1;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else 
 | 
					    else 
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        log(LOG_LEVEL_ERROR, LOG_VERY_COLD_WATER, LOG_VERY_COLD_WATER_CODE);
 | 
					        log(LOG_LEVEL_ERROR, LOG_VERY_COLD_WATER, LOG_VERY_COLD_WATER_CODE);
 | 
				
			||||||
        pumpToRun = -1;
 | 
					        vmPumpToRun = -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // go directly to sleep, skipping the pump loop
 | 
					  // go directly to sleep, skipping the pump loop
 | 
				
			||||||
  if (pumpToRun == -1)
 | 
					  if (vmPumpToRun == -1)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    espDeepSleep();
 | 
					    espDeepSleep();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user