Compare commits
10 Commits
2cfd2afaee
...
7d15cd58d8
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d15cd58d8 | |||
| d06fc52b38 | |||
| c9004e13cb | |||
| 7535042f9a | |||
| 0287da7ff5 | |||
| f95a15dc95 | |||
| a7175989ad | |||
| c235c1fceb | |||
| c5d94bd1da | |||
| 1598d4934a |
@@ -7,6 +7,7 @@
|
|||||||
[factory_settings]
|
[factory_settings]
|
||||||
build_flags =
|
build_flags =
|
||||||
; WiFi settings
|
; WiFi settings
|
||||||
|
|
||||||
-D FACTORY_WIFI_SSID=\"\"
|
-D FACTORY_WIFI_SSID=\"\"
|
||||||
-D FACTORY_WIFI_PASSWORD=\"\"
|
-D FACTORY_WIFI_PASSWORD=\"\"
|
||||||
-D FACTORY_WIFI_HOSTNAME=\"#{platform}-#{unique_id}\" ; supports placeholders
|
-D FACTORY_WIFI_HOSTNAME=\"#{platform}-#{unique_id}\" ; supports placeholders
|
||||||
@@ -30,7 +31,7 @@ build_flags =
|
|||||||
|
|
||||||
; NTP settings
|
; NTP settings
|
||||||
-D FACTORY_NTP_ENABLED=true
|
-D FACTORY_NTP_ENABLED=true
|
||||||
-D FACTORY_NTP_TIME_ZONE_LABEL=\"Europe/London\"
|
-D FACTORY_NTP_TIME_ZONE_LABEL=\"Europe/Brussels\"
|
||||||
-D FACTORY_NTP_TIME_ZONE_FORMAT=\"GMT0BST,M3.5.0/1,M10.5.0\"
|
-D FACTORY_NTP_TIME_ZONE_FORMAT=\"GMT0BST,M3.5.0/1,M10.5.0\"
|
||||||
-D FACTORY_NTP_SERVER=\"time.google.com\"
|
-D FACTORY_NTP_SERVER=\"time.google.com\"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { ValidatorForm } from 'react-material-ui-form-validator';
|
import { ValidatorForm, TextValidator } from 'react-material-ui-form-validator';
|
||||||
|
|
||||||
import { Typography, Box, Checkbox } from '@material-ui/core';
|
import { Typography, Box, Checkbox } from '@material-ui/core';
|
||||||
import SaveIcon from '@material-ui/icons/Save';
|
import SaveIcon from '@material-ui/icons/Save';
|
||||||
@@ -25,7 +25,7 @@ class FanStatusRestController extends Component<FanStatusRestControllerProps> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<SectionContent title='REST Controller' titleGutter>
|
<SectionContent title='Fan Control Settings' titleGutter>
|
||||||
<RestFormLoader
|
<RestFormLoader
|
||||||
{...this.props}
|
{...this.props}
|
||||||
render={props => (
|
render={props => (
|
||||||
@@ -48,9 +48,10 @@ function FanStatusRestControllerForm(props: FanStatusRestControllerFormProps) {
|
|||||||
<ValidatorForm onSubmit={saveData}>
|
<ValidatorForm onSubmit={saveData}>
|
||||||
<Box bgcolor="primary.main" color="primary.contrastText" p={2} mt={2} mb={2}>
|
<Box bgcolor="primary.main" color="primary.contrastText" p={2} mt={2} mb={2}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1">
|
||||||
The form below controls the LED via the RESTful service exposed by the ESP device.
|
The form below allow you to define the fan behaviour depending of the temperature.
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@@ -59,8 +60,85 @@ function FanStatusRestControllerForm(props: FanStatusRestControllerFormProps) {
|
|||||||
color="primary"
|
color="primary"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="Fan State ?"
|
label="Enable Fan"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:100']}
|
||||||
|
errorMessages={['Low Temperature required', "Must be a number", "Must be 0 or higher", "Max value is 100"]}
|
||||||
|
name="temperature_thres_low"
|
||||||
|
label="Low Temperature Threshold (fan start)"
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
value={data.temperature_thres_low}
|
||||||
|
type="number"
|
||||||
|
onChange={handleValueChange('temperature_thres_low')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isNumber', 'minNumber:30', 'maxNumber:200']}
|
||||||
|
errorMessages={['High Temperature required', "Must be a number", "Must be 0 or higher", "Max value is 100"]}
|
||||||
|
name="temperature_thres_high"
|
||||||
|
label="High Temperature Threshold (fan max)"
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
value={data.temperature_thres_high}
|
||||||
|
type="number"
|
||||||
|
onChange={handleValueChange('temperature_thres_high')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:40']}
|
||||||
|
errorMessages={['Fan PWM pin is required', "Must be a number", "Must be 0 or higher", "Max value is 40"]}
|
||||||
|
name="fan_pwm_gpio"
|
||||||
|
label="Fan PWM GPIO pin"
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
value={data.fan_pwm_gpio}
|
||||||
|
type="number"
|
||||||
|
onChange={handleValueChange('fan_pwm_gpio')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:40']}
|
||||||
|
errorMessages={['Fan TACH pin is required', "Must be a number", "Must be 0 or higher", "Max value is 40"]}
|
||||||
|
name="fan_tach_gpio"
|
||||||
|
label="Fan TACH GPIO pin"
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
value={data.fan_tach_gpio}
|
||||||
|
type="number"
|
||||||
|
onChange={handleValueChange('fan_tach_gpio')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:40']}
|
||||||
|
errorMessages={['Temp Sensor pin is required', "Must be a number", "Must be 0 or higher", "Max value is 40"]}
|
||||||
|
name="oneWire_gpio"
|
||||||
|
label="Sensor OneWire DS1820 gpio"
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
value={data.oneWire_gpio}
|
||||||
|
type="number"
|
||||||
|
onChange={handleValueChange('oneWire_gpio')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:100000']}
|
||||||
|
errorMessages={['Fan MAX is required', "Must be a number", "Must be 0 or higher", "Max value is 1024"]}
|
||||||
|
name="fan_max_speed"
|
||||||
|
label="Fan Max RPM Speed"
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
value={data.fan_max_speed}
|
||||||
|
type="number"
|
||||||
|
onChange={handleValueChange('fan_max_speed')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
<FormActions>
|
<FormActions>
|
||||||
<FormButton startIcon={<SaveIcon />} variant="contained" color="primary" type="submit">
|
<FormButton startIcon={<SaveIcon />} variant="contained" color="primary" type="submit">
|
||||||
Save
|
Save
|
||||||
|
|||||||
@@ -13,4 +13,8 @@ export interface FanStatus {
|
|||||||
temperature_thres_low : number;
|
temperature_thres_low : number;
|
||||||
temperature_thres_high : number;
|
temperature_thres_high : number;
|
||||||
fan_status : boolean;
|
fan_status : boolean;
|
||||||
|
fan_pwm_gpio : number;
|
||||||
|
fan_tach_gpio : number;
|
||||||
|
fan_max_speed : number;
|
||||||
|
oneWire_gpio : number;
|
||||||
}
|
}
|
||||||
BIN
media/esp8266-pinout.png
Normal file
BIN
media/esp8266-pinout.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 617 KiB |
112
platformio.ini
112
platformio.ini
@@ -1,49 +1,99 @@
|
|||||||
|
; 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
|
||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
extra_configs =
|
extra_configs =
|
||||||
factory_settings.ini
|
factory_settings.ini
|
||||||
features.ini
|
features.ini
|
||||||
default_envs = esp12e
|
default_envs =
|
||||||
;default_envs = node32s
|
esp12e
|
||||||
|
node32s
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
build_flags=
|
build_flags =
|
||||||
${factory_settings.build_flags}
|
${factory_settings.build_flags}
|
||||||
${features.build_flags}
|
${features.build_flags}
|
||||||
-D NO_GLOBAL_ARDUINOOTA
|
-D NO_GLOBAL_ARDUINOOTA
|
||||||
; Uncomment ENABLE_CORS to enable Cross-Origin Resource Sharing (required for local React development)
|
-D ENABLE_CORS
|
||||||
-D ENABLE_CORS
|
-D CORS_ORIGIN=\"http://localhost:3000\"
|
||||||
-D CORS_ORIGIN=\"http://localhost:3000\"
|
-D PROGMEM_WWW
|
||||||
; Uncomment PROGMEM_WWW to enable the storage of the WWW data in PROGMEM
|
|
||||||
-D PROGMEM_WWW
|
|
||||||
|
|
||||||
; ensure transitive dependencies are included for correct platforms only
|
|
||||||
lib_compat_mode = strict
|
lib_compat_mode = strict
|
||||||
|
|
||||||
; Uncomment & modify the lines below in order to configure OTA updates
|
|
||||||
;upload_flags =
|
|
||||||
; --port=8266
|
|
||||||
; --auth=esp-react
|
|
||||||
;upload_port = 192.168.0.11
|
|
||||||
|
|
||||||
framework = arduino
|
framework = arduino
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
extra_scripts = pre:scripts/build_interface.py
|
||||||
|
lib_deps =
|
||||||
|
ArduinoJson@>=6.0.0,<7.0.0
|
||||||
|
ESP Async WebServer@>=1.2.0,<2.0.0
|
||||||
|
AsyncMqttClient@>=0.8.2,<1.0.0
|
||||||
|
|
||||||
extra_scripts =
|
|
||||||
pre:scripts/build_interface.py
|
|
||||||
|
|
||||||
lib_deps =
|
|
||||||
ArduinoJson@>=6.0.0,<7.0.0
|
|
||||||
ESP Async WebServer@>=1.2.0,<2.0.0
|
|
||||||
AsyncMqttClient@>=0.8.2,<1.0.0
|
|
||||||
|
|
||||||
[env:esp12e]
|
[env:esp12e]
|
||||||
platform = espressif8266
|
platform = espressif8266
|
||||||
board = esp12e
|
board = esp12e
|
||||||
board_build.f_cpu = 160000000L
|
board_build.f_cpu = 160000000L
|
||||||
board_build.filesystem = littlefs
|
board_build.filesystem = littlefs
|
||||||
|
lib_deps = milesburton/DallasTemperature@^3.9.1
|
||||||
|
|
||||||
[env:node32s]
|
[env:node32s]
|
||||||
; Comment out min_spiffs.csv setting if disabling PROGMEM_WWW with ESP32
|
|
||||||
board_build.partitions = min_spiffs.csv
|
board_build.partitions = min_spiffs.csv
|
||||||
platform = espressif32
|
platform = espressif32
|
||||||
board = node32s
|
board = node32s
|
||||||
|
lib_deps = milesburton/DallasTemperature@^3.9.1
|
||||||
|
|
||||||
|
[factory_settings]
|
||||||
|
build_flags =
|
||||||
|
|
||||||
|
-D FACTORY_WIFI_SSID=\"\"
|
||||||
|
-D FACTORY_WIFI_PASSWORD=\"\"
|
||||||
|
-D FACTORY_WIFI_HOSTNAME=\"#{platform}-#{unique_id}\"
|
||||||
|
|
||||||
|
-D FACTORY_AP_PROVISION_MODE=AP_MODE_DISCONNECTED
|
||||||
|
-D FACTORY_AP_SSID=\"ESP8266-React-#{unique_id}\"
|
||||||
|
-D FACTORY_AP_PASSWORD=\"esp-react\"
|
||||||
|
-D FACTORY_AP_CHANNEL=1
|
||||||
|
-D FACTORY_AP_SSID_HIDDEN=false
|
||||||
|
-D FACTORY_AP_MAX_CLIENTS=4
|
||||||
|
-D FACTORY_AP_LOCAL_IP=\"192.168.4.1\"
|
||||||
|
-D FACTORY_AP_GATEWAY_IP=\"192.168.4.1\"
|
||||||
|
-D FACTORY_AP_SUBNET_MASK=\"255.255.255.0\"
|
||||||
|
|
||||||
|
-D FACTORY_ADMIN_USERNAME=\"admin\"
|
||||||
|
-D FACTORY_ADMIN_PASSWORD=\"admin\"
|
||||||
|
-D FACTORY_GUEST_USERNAME=\"guest\"
|
||||||
|
-D FACTORY_GUEST_PASSWORD=\"guest\"
|
||||||
|
|
||||||
|
-D FACTORY_NTP_ENABLED=true
|
||||||
|
-D FACTORY_NTP_TIME_ZONE_LABEL=\"Europe/Brussels\"
|
||||||
|
-D FACTORY_NTP_TIME_ZONE_FORMAT=\"GMT0BST,M3.5.0/1,M10.5.0\"
|
||||||
|
-D FACTORY_NTP_SERVER=\"time.google.com\"
|
||||||
|
|
||||||
|
-D FACTORY_OTA_PORT=8266
|
||||||
|
-D FACTORY_OTA_PASSWORD=\"esp-react\"
|
||||||
|
-D FACTORY_OTA_ENABLED=true
|
||||||
|
|
||||||
|
-D FACTORY_MQTT_ENABLED=false
|
||||||
|
-D FACTORY_MQTT_HOST=\"test.mosquitto.org\"
|
||||||
|
-D FACTORY_MQTT_PORT=1883
|
||||||
|
-D FACTORY_MQTT_USERNAME=\"\"
|
||||||
|
-D FACTORY_MQTT_PASSWORD=\"\"
|
||||||
|
-D FACTORY_MQTT_CLIENT_ID=\"#{platform}-#{unique_id}\"
|
||||||
|
-D FACTORY_MQTT_KEEP_ALIVE=60
|
||||||
|
-D FACTORY_MQTT_CLEAN_SESSION=true
|
||||||
|
-D FACTORY_MQTT_MAX_TOPIC_LENGTH=128
|
||||||
|
|
||||||
|
-D FACTORY_JWT_SECRET=\"#{random}-#{random}\"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
build_flags =
|
||||||
|
-D FT_PROJECT=1
|
||||||
|
-D FT_SECURITY=1
|
||||||
|
-D FT_MQTT=1
|
||||||
|
-D FT_NTP=1
|
||||||
|
-D FT_OTA=1
|
||||||
|
-D FT_UPLOAD_FIRMWARE=1
|
||||||
|
|||||||
16
src/FanMqttSettingsService.cpp
Normal file
16
src/FanMqttSettingsService.cpp
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#include <FanMqttSettingsService.h>
|
||||||
|
|
||||||
|
FanMqttSettingsService::FanMqttSettingsService(AsyncWebServer* server, FS* fs, SecurityManager* securityManager) :
|
||||||
|
_httpEndpoint(FanMqttSettings::read,
|
||||||
|
FanMqttSettings::update,
|
||||||
|
this,
|
||||||
|
server,
|
||||||
|
LIGHT_BROKER_SETTINGS_PATH,
|
||||||
|
securityManager,
|
||||||
|
AuthenticationPredicates::IS_AUTHENTICATED),
|
||||||
|
_fsPersistence(FanMqttSettings::read, FanMqttSettings::update, this, fs, LIGHT_BROKER_SETTINGS_FILE) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void FanMqttSettingsService::begin() {
|
||||||
|
_fsPersistence.readFromFS();
|
||||||
|
}
|
||||||
41
src/FanMqttSettingsService.h
Normal file
41
src/FanMqttSettingsService.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef FanMqttSettingsService_h
|
||||||
|
#define FanMqttSettingsService_h
|
||||||
|
|
||||||
|
#include <HttpEndpoint.h>
|
||||||
|
#include <FSPersistence.h>
|
||||||
|
#include <SettingValue.h>
|
||||||
|
|
||||||
|
#define LIGHT_BROKER_SETTINGS_FILE "/config/brokerSettings.json"
|
||||||
|
#define LIGHT_BROKER_SETTINGS_PATH "/rest/brokerSettings"
|
||||||
|
|
||||||
|
class FanMqttSettings {
|
||||||
|
public:
|
||||||
|
String mqttPath;
|
||||||
|
String name;
|
||||||
|
String uniqueId;
|
||||||
|
|
||||||
|
static void read(FanMqttSettings& settings, JsonObject& root) {
|
||||||
|
root["mqtt_path"] = settings.mqttPath;
|
||||||
|
root["name"] = settings.name;
|
||||||
|
root["unique_id"] = settings.uniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
static StateUpdateResult update(JsonObject& root, FanMqttSettings& settings) {
|
||||||
|
settings.mqttPath = root["mqtt_path"] | SettingValue::format("homeassistant/fan/#{unique_id}");
|
||||||
|
settings.name = root["name"] | SettingValue::format("light-#{unique_id}");
|
||||||
|
settings.uniqueId = root["unique_id"] | SettingValue::format("light-#{unique_id}");
|
||||||
|
return StateUpdateResult::CHANGED;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FanMqttSettingsService : public StatefulService<FanMqttSettings> {
|
||||||
|
public:
|
||||||
|
FanMqttSettingsService(AsyncWebServer* server, FS* fs, SecurityManager* securityManager);
|
||||||
|
void begin();
|
||||||
|
|
||||||
|
private:
|
||||||
|
HttpEndpoint<FanMqttSettings> _httpEndpoint;
|
||||||
|
FSPersistence<FanMqttSettings> _fsPersistence;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // end FanMqttSettingsService_h
|
||||||
@@ -1,15 +1,23 @@
|
|||||||
#include <FanStateService.h>
|
#include <FanStateService.h>
|
||||||
|
|
||||||
FanStateService::FanStateService(AsyncWebServer* server,
|
|
||||||
SecurityManager* securityManager) :
|
|
||||||
|
FanStateService::FanStateService(AsyncWebServer* server, FS* fs, SecurityManager* securityManager, AsyncMqttClient* mqttClient, FanMqttSettingsService* fanMQTTSettingsService) :
|
||||||
_httpEndpoint(FanState::read,
|
_httpEndpoint(FanState::read,
|
||||||
FanState::update,
|
FanState::update,
|
||||||
this,
|
this,
|
||||||
server,
|
server,
|
||||||
FAN_SETTINGS_ENDPOINT_PATH,
|
FAN_SETTINGS_ENDPOINT_PATH,
|
||||||
securityManager,
|
securityManager,
|
||||||
AuthenticationPredicates::IS_AUTHENTICATED) {
|
AuthenticationPredicates::IS_AUTHENTICATED),
|
||||||
pinMode(FAN_PIN, OUTPUT);
|
_mqttPubSub(FanState::haRead, FanState::haUpdate, this, mqttClient,"testmqtt1/set","testmqtt1/state"),
|
||||||
|
_fsPersistence(FanState::read,
|
||||||
|
FanState::update,
|
||||||
|
this,
|
||||||
|
fs,
|
||||||
|
FAN_SETTINGS_FILE) {
|
||||||
|
// pinMode(FAN_PIN, OUTPUT);
|
||||||
|
pinMode(_state.fanPwmGPIO, OUTPUT);
|
||||||
// configure settings service update handler to update LED state
|
// configure settings service update handler to update LED state
|
||||||
addUpdateHandler([&](const String& originId) { onConfigUpdated(); }, false);
|
addUpdateHandler([&](const String& originId) { onConfigUpdated(); }, false);
|
||||||
}
|
}
|
||||||
@@ -17,12 +25,51 @@ FanStateService::FanStateService(AsyncWebServer* server,
|
|||||||
|
|
||||||
void FanStateService::begin() {
|
void FanStateService::begin() {
|
||||||
_state.fanStatus = DEFAULT_FAN_STATE;
|
_state.fanStatus = DEFAULT_FAN_STATE;
|
||||||
Serial.print("Starting The Fan Service");
|
Serial.println("Starting The Fan Service + read from FS");
|
||||||
|
_fsPersistence.readFromFS();
|
||||||
|
|
||||||
|
this->oneWire1.begin(_state.OneWireGPIO);
|
||||||
|
this->sensor_intake.setOneWire(&this->oneWire1);
|
||||||
|
this->sensor_intake.begin();
|
||||||
|
|
||||||
|
// attachInterrupt(_state.fanTachGPIO,handleInterrupt,RISING);
|
||||||
|
|
||||||
onConfigUpdated();
|
onConfigUpdated();
|
||||||
|
lastpoll = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FanStateService::SetLastPoll(unsigned long l) {
|
||||||
|
this->lastpoll = l;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int FanStateService::getTachGPIO() {
|
||||||
|
return _state.fanTachGPIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FanStateService::onConfigUpdated() {
|
void FanStateService::onConfigUpdated() {
|
||||||
Serial.print(" ** Fan UPDATE ");
|
Serial.println(" ** Fan UPDATE (pin " + (String)_state.fanPwmGPIO + ") to " + _state.fanMaxSpeed);
|
||||||
digitalWrite(FAN_PIN, _state.fanStatus ? FAN_ON : FAN_OFF);
|
//digitalWrite(FAN_PIN, _state.fanStatus ? FAN_ON : FAN_OFF);
|
||||||
|
analogWrite(_state.fanPwmGPIO, _state.fanMaxSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FanStateService::save() {
|
||||||
|
Serial.println(" ** Fan Write to FS ");
|
||||||
|
_fsPersistence.writeToFS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FanStateService::compute() {
|
||||||
|
unsigned long period = millis() - this->lastpoll;
|
||||||
|
this->sensor_intake.requestTemperatures();
|
||||||
|
_state.Tin = this->sensor_intake.getTempCByIndex(0);
|
||||||
|
|
||||||
|
_state.Tout = this->sensor_intake.getTempCByIndex(1);
|
||||||
|
_state.RPM = 60000/period*this->ROT/2; // Hall sensor = 2 tick per rotation
|
||||||
|
Serial.print("Intake: " + (String) _state.Tin + " - " + (String) _state.Tout + " [ "+ (String) _state.RPM + " RPM ]\n");
|
||||||
|
this->ROT=0;
|
||||||
|
|
||||||
|
this->_mqttPubSub.setPubTopic("testmqtt1/state");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,16 +1,25 @@
|
|||||||
#ifndef FanStateService_h
|
#ifndef FanStateService_h
|
||||||
#define FanStateService_h
|
#define FanStateService_h
|
||||||
|
|
||||||
|
#include <FSPersistence.h>
|
||||||
#include <HttpEndpoint.h>
|
#include <HttpEndpoint.h>
|
||||||
|
#include <FanMqttSettingsService.h>
|
||||||
|
#include <MqttPubSub.h>
|
||||||
|
|
||||||
|
#include <OneWire.h>
|
||||||
|
#include <DallasTemperature.h>
|
||||||
|
|
||||||
#define FAN_PIN 13
|
|
||||||
#define PRINT_DELAY 5000
|
#define PRINT_DELAY 5000
|
||||||
|
|
||||||
#define DEFAULT_FAN_STATE false
|
#define DEFAULT_FAN_STATE false
|
||||||
#define OFF_STATE "OFF"
|
#define DEFAULT_FAN_PWM_GPIO 12
|
||||||
#define ON_STATE "ON"
|
#define DEFAULT_FAN_TACH_GPIO 13
|
||||||
|
#define DEFAULT_ONEWIRE_GPIO 14
|
||||||
|
#define DEFAULT_THRES_LOW 25
|
||||||
|
#define DEFAULT_THRES_HIGH 70
|
||||||
|
#define DEFAULT_FAN_MAX_SPEED 1021
|
||||||
|
#define OFF_STATE "OFF"
|
||||||
|
#define ON_STATE "ON"
|
||||||
|
|
||||||
// Note that the built-in LED is on when the pin is low on most NodeMCU boards.
|
// Note that the built-in LED is on when the pin is low on most NodeMCU boards.
|
||||||
// This is because the anode is tied to VCC and the cathode to the GPIO 4 (Arduino pin 2).
|
// This is because the anode is tied to VCC and the cathode to the GPIO 4 (Arduino pin 2).
|
||||||
@@ -22,6 +31,7 @@
|
|||||||
#define FAN_OFF 0x1
|
#define FAN_OFF 0x1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define FAN_SETTINGS_FILE "/config/fanSettings.json"
|
||||||
#define FAN_SETTINGS_ENDPOINT_PATH "/rest/fanState"
|
#define FAN_SETTINGS_ENDPOINT_PATH "/rest/fanState"
|
||||||
|
|
||||||
|
|
||||||
@@ -29,33 +39,85 @@ class FanState {
|
|||||||
public:
|
public:
|
||||||
bool fanStatus;
|
bool fanStatus;
|
||||||
int fanSpeed;
|
int fanSpeed;
|
||||||
|
int fanPwmGPIO;
|
||||||
|
int fanTachGPIO;
|
||||||
|
int fanMaxSpeed;
|
||||||
|
int thresLow;
|
||||||
|
int thresHigh;
|
||||||
|
|
||||||
|
float Tin;
|
||||||
|
float Tout;
|
||||||
|
float RPM;
|
||||||
|
|
||||||
|
int OneWireGPIO;
|
||||||
|
float sensorInTemp;
|
||||||
|
float sensorOutTemp;
|
||||||
|
|
||||||
static void read(FanState& settings, JsonObject& root) {
|
static void read(FanState& settings, JsonObject& root) {
|
||||||
root["fan_status"] = settings.fanStatus;
|
root["oneWire_gpio"] = settings.OneWireGPIO;
|
||||||
String s = root["fan_status"];
|
root["sensor_in_temp"] = settings.sensorInTemp;
|
||||||
Serial.print(" ** Fan read [" + s + "]\n");
|
root["sensor_out_temp"] = settings.sensorOutTemp;
|
||||||
|
root["fan_status"] = settings.fanStatus;
|
||||||
|
root["fan_pwm_gpio"] = settings.fanPwmGPIO;
|
||||||
|
root["fan_tach_gpio"] = settings.fanTachGPIO;
|
||||||
|
root["fan_max_speed"] = settings.fanMaxSpeed;
|
||||||
|
root["temperature_thres_low"] = settings.thresLow;
|
||||||
|
root["temperature_thres_high"] = settings.thresHigh;
|
||||||
|
// String s = (String)root["fan_status"] + "|" + (String)root["fan_gpio"] + "|" + (String)root["fan_max_speed"] + "|" + (String)root["temperature_thres_low"] + "|" + (String)root["temperature_thres_high"];
|
||||||
|
String s = root["fan_status"]; Serial.println(" ** Fan read [fan_status : " + s + "]");
|
||||||
|
String t = root["fan_pwm_gpio"]; Serial.println(" ** Fan read [fan_pwm_gpio : " + t + "]");
|
||||||
|
String u = root["fan_tach_gpio"]; Serial.println(" ** Fan read [fan_tach_gpio : " + u + "]");
|
||||||
|
String v = root["fan_max_speed"]; Serial.println(" ** Fan read [fan_max_speed : " + v + "]");
|
||||||
|
String w = root["temperature_thres_low"]; Serial.println(" ** Fan read [temperature_thres_low : " + w + "]");
|
||||||
|
String x = root["temperature_thres_high"]; Serial.println(" ** Fan read [temperature_thres_high : " + x + "]");
|
||||||
|
String y = root["oneWire_gpio"]; Serial.println(" ** Fan read [oneWire_gpio : " + y + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
static StateUpdateResult update(JsonObject& root, FanState& fanState) {
|
static StateUpdateResult update(JsonObject& root, FanState& fanState) {
|
||||||
boolean newState = root["fan_status"] | DEFAULT_FAN_STATE;
|
boolean newFanState = root["fan_status"] | DEFAULT_FAN_STATE;
|
||||||
Serial.print(" ** Fan update [" + (String)newState + "]\n");
|
int newFanPwmGPIO = root["fan_pwm_gpio"] | DEFAULT_FAN_PWM_GPIO;
|
||||||
if (fanState.fanStatus != newState) {
|
int newFanTachGPIO = root["fan_tach_gpio"] | DEFAULT_FAN_TACH_GPIO;
|
||||||
fanState.fanStatus = newState;
|
int newMaxSpeed = root["fan_max_speed"] | DEFAULT_FAN_MAX_SPEED;
|
||||||
|
int newThresLow = root["temperature_thres_low"] | DEFAULT_THRES_LOW;
|
||||||
|
int newThresHigh = root["temperature_thres_high"] | DEFAULT_THRES_HIGH;
|
||||||
|
int newOneWireGPIO = root["oneWire_gpio"] | DEFAULT_ONEWIRE_GPIO;
|
||||||
|
/*
|
||||||
|
Serial.println(" ** Fan update [status:" + (String)newFanState + "|gpio:" + (String)newFanPwmGPIO + "|mxspd:" + (String)newMaxSpeed + "|low:" + (String)newThresLow + "|high:" + (String)newThresHigh + "]");
|
||||||
|
*/
|
||||||
|
if ( fanState.fanStatus != newFanState
|
||||||
|
|| fanState.fanPwmGPIO != newFanPwmGPIO
|
||||||
|
|| fanState.fanTachGPIO != newFanTachGPIO
|
||||||
|
|| fanState.fanMaxSpeed != newMaxSpeed
|
||||||
|
|| fanState.thresLow != newThresLow
|
||||||
|
|| fanState.thresHigh != newThresHigh
|
||||||
|
|| fanState.OneWireGPIO != newOneWireGPIO ) {
|
||||||
|
fanState.fanStatus = newFanState;
|
||||||
|
fanState.fanPwmGPIO = newFanPwmGPIO;
|
||||||
|
fanState.fanTachGPIO = newFanTachGPIO;
|
||||||
|
fanState.fanMaxSpeed = newMaxSpeed;
|
||||||
|
fanState.thresLow = newThresLow;
|
||||||
|
fanState.thresHigh = newThresHigh;
|
||||||
|
fanState.OneWireGPIO = newOneWireGPIO;
|
||||||
|
Serial.println(" ** Fan CONFIG : CHANGED");
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
}
|
}
|
||||||
|
Serial.println(" ** Fan CONFIG : UNCHANGED");
|
||||||
return StateUpdateResult::UNCHANGED;
|
return StateUpdateResult::UNCHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void haRead(FanState& settings, JsonObject& root) {
|
static void haRead(FanState& settings, JsonObject& root) {
|
||||||
root["state"] = settings.fanStatus ? ON_STATE : OFF_STATE;
|
root["state"] = settings.fanStatus ? ON_STATE : OFF_STATE;
|
||||||
|
root["Tinput"] = settings.Tin;
|
||||||
|
root["Toutput"] = settings.Tout;
|
||||||
|
root["RPM"] = settings.RPM;
|
||||||
String s = root["state"];
|
String s = root["state"];
|
||||||
Serial.print(" ** Fan haRead [" + s + "] \n");
|
Serial.println(" ** Fan haRead [" + s + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
static StateUpdateResult haUpdate(JsonObject& root, FanState& fanState) {
|
static StateUpdateResult haUpdate(JsonObject& root, FanState& fanState) {
|
||||||
String state = root["state"];
|
String state = root["state"];
|
||||||
String s = root["state"];
|
String s = root["state"];
|
||||||
Serial.print(" ** Fan haUpdate [" + s + "] \n");
|
Serial.println(" ** Fan haUpdate [" + s + "]");
|
||||||
// parse new led state
|
// parse new led state
|
||||||
boolean newState = false;
|
boolean newState = false;
|
||||||
if (state.equals(ON_STATE)) {
|
if (state.equals(ON_STATE)) {
|
||||||
@@ -74,11 +136,26 @@ class FanState {
|
|||||||
|
|
||||||
class FanStateService : public StatefulService<FanState> {
|
class FanStateService : public StatefulService<FanState> {
|
||||||
public:
|
public:
|
||||||
FanStateService(AsyncWebServer* server, SecurityManager* securityManager);
|
unsigned long lastpoll;
|
||||||
|
OneWire oneWire1;
|
||||||
|
DallasTemperature sensor_intake;
|
||||||
|
|
||||||
|
unsigned int ROT;
|
||||||
|
|
||||||
|
FanStateService(AsyncWebServer* server, FS* fs, SecurityManager* securityManager, AsyncMqttClient* mqttClient, FanMqttSettingsService* fanMQTTSettingsService);
|
||||||
void begin();
|
void begin();
|
||||||
|
void save();
|
||||||
|
void compute();
|
||||||
|
void SetLastPoll(unsigned long l);
|
||||||
|
int getTachGPIO();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HttpEndpoint<FanState> _httpEndpoint;
|
HttpEndpoint<FanState> _httpEndpoint;
|
||||||
|
FSPersistence<FanState> _fsPersistence;
|
||||||
|
|
||||||
|
FanMqttSettingsService* _fanMQTTSettingsService;
|
||||||
|
AsyncMqttClient* _mqttClient;
|
||||||
|
MqttPubSub<FanState> _mqttPubSub;
|
||||||
|
|
||||||
void registerConfig();
|
void registerConfig();
|
||||||
void onConfigUpdated();
|
void onConfigUpdated();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <LightStateService.h>
|
#include <LightStateService.h>
|
||||||
|
|
||||||
|
|
||||||
LightStateService::LightStateService(AsyncWebServer* server,
|
LightStateService::LightStateService(AsyncWebServer* server,
|
||||||
SecurityManager* securityManager,
|
SecurityManager* securityManager,
|
||||||
AsyncMqttClient* mqttClient,
|
AsyncMqttClient* mqttClient,
|
||||||
|
|||||||
51
src/main.cpp
51
src/main.cpp
@@ -4,23 +4,39 @@
|
|||||||
#include <LightStateService.h>
|
#include <LightStateService.h>
|
||||||
*/
|
*/
|
||||||
#include <FanStateService.h>
|
#include <FanStateService.h>
|
||||||
|
#include <FanMqttSettingsService.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define ONE_WIRE_BUS 14
|
||||||
|
#define SERIAL_BAUD_RATE 115200
|
||||||
|
#define PWM_PROBE_MS 5000
|
||||||
|
|
||||||
#define SERIAL_BAUD_RATE 115200
|
|
||||||
|
|
||||||
AsyncWebServer server(80);
|
AsyncWebServer server(80);
|
||||||
ESP8266React esp8266React(&server);
|
|
||||||
/*
|
|
||||||
LightMqttSettingsService lightMqttSettingsService =
|
|
||||||
LightMqttSettingsService(&server, esp8266React.getFS(), esp8266React.getSecurityManager());
|
|
||||||
|
|
||||||
LightStateService lightStateService = LightStateService(&server,
|
ESP8266React esp8266React(&server);
|
||||||
esp8266React.getSecurityManager(),
|
|
||||||
esp8266React.getMqttClient(),
|
FanMqttSettingsService fanMqttSettingsService = FanMqttSettingsService(
|
||||||
&lightMqttSettingsService);
|
&server,
|
||||||
|
esp8266React.getFS(),
|
||||||
|
esp8266React.getSecurityManager()
|
||||||
|
);
|
||||||
|
FanStateService fanStateService = FanStateService (
|
||||||
|
&server,
|
||||||
|
esp8266React.getFS(),
|
||||||
|
esp8266React.getSecurityManager(),
|
||||||
|
esp8266React.getMqttClient(),
|
||||||
|
&fanMqttSettingsService
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ICACHE_RAM_ATTR handleInterrupt() {
|
||||||
|
fanStateService.ROT++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
FanStateService fanStateService = FanStateService(&server,esp8266React.getSecurityManager());
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// start serial and filesystem
|
// start serial and filesystem
|
||||||
@@ -32,16 +48,29 @@ void setup() {
|
|||||||
// load the initial light settings
|
// load the initial light settings
|
||||||
fanStateService.begin();
|
fanStateService.begin();
|
||||||
|
|
||||||
|
// Serial.println(" FAN GPIO = " + fanStateService.fan);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// start the light service
|
// start the light service
|
||||||
lightMqttSettingsService.begin();
|
lightMqttSettingsService.begin();
|
||||||
*/
|
*/
|
||||||
|
fanMqttSettingsService.begin();
|
||||||
|
|
||||||
|
pinMode(fanStateService.getTachGPIO(),INPUT);
|
||||||
|
attachInterrupt(fanStateService.getTachGPIO(),handleInterrupt,RISING);
|
||||||
|
|
||||||
// start the server
|
// start the server
|
||||||
server.begin();
|
server.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
// run the framework's loop function
|
// run the framework's loop function
|
||||||
|
|
||||||
|
if( ( millis() - fanStateService.lastpoll ) > PWM_PROBE_MS ) {
|
||||||
|
fanStateService.compute();
|
||||||
|
fanStateService.SetLastPoll(millis());
|
||||||
|
}
|
||||||
|
|
||||||
esp8266React.loop();
|
esp8266React.loop();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user