Compare commits
4 Commits
37e8f1bfca
...
72f63d21f9
Author | SHA1 | Date |
---|---|---|
Dirk Jahnke | 72f63d21f9 | |
Dirk Jahnke | 79bc78b511 | |
Dirk Jahnke | 2588d8beb5 | |
Dirk Jahnke | 215be19b47 |
|
@ -0,0 +1,69 @@
|
||||||
|
# Copyright (c) 2019-present Dirk Jahnke (dirk.jahnke@mailbox.org)
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
from platformio import util
|
||||||
|
import shutil
|
||||||
|
import gzip
|
||||||
|
|
||||||
|
Import('env')
|
||||||
|
|
||||||
|
#print env
|
||||||
|
#print env.Dump()
|
||||||
|
|
||||||
|
project_config = util.load_project_config()
|
||||||
|
version = project_config.get("common", "app_version")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Transfer and gzip files to proj/data directory
|
||||||
|
#
|
||||||
|
|
||||||
|
def transfer_file(source, target):
|
||||||
|
""" copy and compress the file """
|
||||||
|
|
||||||
|
try:
|
||||||
|
with gzip.open(target + '.gz', 'wb') as target_fid:
|
||||||
|
with open(source, 'rb') as source_fid:
|
||||||
|
target_fid.writelines(source_fid)
|
||||||
|
print('Compress {}'.format(source))
|
||||||
|
except FileNotFoundError:
|
||||||
|
os.makedirs(os.path.dirname(target))
|
||||||
|
transfer_file(source, target)
|
||||||
|
|
||||||
|
|
||||||
|
def build_files(source, target, env):
|
||||||
|
# copy & gzip files from src/data to data
|
||||||
|
#firmware_path = str(source[0])
|
||||||
|
#firmware_name = os.path.basename(firmware_path)
|
||||||
|
source_path = os.path.join(env['PROJECTSRC_DIR'], "data")
|
||||||
|
destination_path = env['PROJECTDATA_DIR']
|
||||||
|
|
||||||
|
print("========= Preparing file system (SPIFF) files from " + source_path)
|
||||||
|
print("=== Destination: " + destination_path)
|
||||||
|
print("Cleanup destination path " + destination_path)
|
||||||
|
shutil.rmtree(destination_path)
|
||||||
|
os.mkdir(destination_path)
|
||||||
|
|
||||||
|
for path, _, files in os.walk(source_path):
|
||||||
|
for file in files:
|
||||||
|
source = os.path.join(path, file)
|
||||||
|
target = os.path.join(destination_path, file)
|
||||||
|
print("Copy " + source + " to " + target)
|
||||||
|
transfer_file(source, target)
|
||||||
|
|
||||||
|
# Custom upload command and program name
|
||||||
|
#env.AddPreAction("$BUILD_DIR/spiffs.bin", build_files)
|
||||||
|
#env.AddPreAction("$BUILD_DIR/firmware.bin", build_files)
|
||||||
|
env.AddPreAction("buildprog", build_files)
|
|
@ -8,19 +8,68 @@
|
||||||
; Please visit documentation for the other options and examples
|
; Please visit documentation for the other options and examples
|
||||||
; https://docs.platformio.org/page/projectconf.html
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
[env:d1_mini]
|
[platformio]
|
||||||
platform = espressif8266
|
env_default = debug_wlan
|
||||||
board = d1_mini
|
|
||||||
framework = arduino
|
|
||||||
|
|
||||||
|
[common]
|
||||||
|
app_version = 0.2.22
|
||||||
|
platform = espressif8266
|
||||||
lib_deps =
|
lib_deps =
|
||||||
# Using a library name
|
|
||||||
MD_Parola
|
|
||||||
MD_MAX72XX
|
|
||||||
IOTAppStory-ESP
|
|
||||||
NTPClient
|
NTPClient
|
||||||
ESPAsyncTCP
|
ESPAsyncTCP
|
||||||
ESP Async WebServer
|
ESP Async WebServer
|
||||||
|
IOTAppStory-ESP
|
||||||
|
|
||||||
|
build_flags =
|
||||||
|
'-DAPP_VERSION="{$common.app_version}"'
|
||||||
|
'-DFS_UPDATE_BASE_URL="{$iotjunkie.baseurl}/{$iotjunkie.repository}"'
|
||||||
|
'-DFS_UPDATE_AUTH_USER="{$iotjunkie.user}"'
|
||||||
|
'-DFS_UPDATE_AUTH_PASSWORD="{$iotjunkie.password}"'
|
||||||
|
|
||||||
|
[env:debug_usb]
|
||||||
|
platform = ${common.platform}
|
||||||
|
board = d1_mini
|
||||||
|
framework = arduino
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags}
|
||||||
|
lib_deps =
|
||||||
|
${common.lib_deps}
|
||||||
|
MD_Parola
|
||||||
|
MD_MAX72XX
|
||||||
upload_port = /dev/cu.wchusbserial1420
|
upload_port = /dev/cu.wchusbserial1420
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
|
monitor_speed = 115200
|
||||||
|
|
||||||
|
[env:debug_wlan]
|
||||||
|
platform = ${common.platform}
|
||||||
|
board = d1_mini
|
||||||
|
framework = arduino
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags}
|
||||||
|
lib_deps =
|
||||||
|
${common.lib_deps}
|
||||||
|
MD_Parola
|
||||||
|
MD_MAX72XX
|
||||||
|
;upload_port = /dev/cu.wchusbserial1420
|
||||||
|
;upload_speed = 921600
|
||||||
|
monitor_speed = 115200
|
||||||
|
upload_protocol = custom
|
||||||
|
;upload_port = 192.168.89.72
|
||||||
|
extra_scripts =
|
||||||
|
build_files.py
|
||||||
|
;post:publish_firmware.py
|
||||||
|
|
||||||
|
[env:build]
|
||||||
|
;extra_scripts = pre:build_files.py
|
||||||
|
|
||||||
|
[env:uploadfs]
|
||||||
|
;extra_scripts = pre:publish_files.py
|
||||||
|
|
||||||
|
[iotjunkie]
|
||||||
|
user = fcclient
|
||||||
|
password = 63Gs59PWveT6uQSh
|
||||||
|
baseurl = http://ota.iotjunkie.org
|
||||||
|
repository = fcclient
|
||||||
|
;package = bintray-secure-ota
|
||||||
|
; api_token = ***
|
||||||
|
;api_token = ${sysenv.BINTRAY_API_TOKEN}
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
# Copyright (c) 2019-present Dirk Jahnke (dirk.jahnke@mailbox.org)
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from os.path import basename
|
||||||
|
from platformio import util
|
||||||
|
|
||||||
|
Import('env')
|
||||||
|
|
||||||
|
project_config = util.load_project_config()
|
||||||
|
iotjunkie_config = {k: v for k, v in project_config.items("iotjunkie")}
|
||||||
|
version = project_config.get("common", "app_version")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Push new firmware to the iojunkie storage using API
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
def publish_files(source, target, env):
|
||||||
|
firmware_path = str(source[0])
|
||||||
|
firmware_name = basename(firmware_path)
|
||||||
|
|
||||||
|
print("Uploading {0} to IOTJunkie. Version: {1}".format(
|
||||||
|
firmware_name, version))
|
||||||
|
|
||||||
|
url = "/".join([
|
||||||
|
"https://api.iotjunkie.org", "content",
|
||||||
|
iotjunkie_config.get("user"),
|
||||||
|
iotjunkie_config.get("repository"),
|
||||||
|
version, firmware_name
|
||||||
|
])
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Content-type": "application/octet-stream",
|
||||||
|
"X-IOTJunkie-Publish": "1",
|
||||||
|
"X-IOTJunkie-Override": "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
r = requests.put(
|
||||||
|
url,
|
||||||
|
data=open(firmware_path, "rb"),
|
||||||
|
headers=headers,
|
||||||
|
auth=(iotjunkie_config.get("user"), iotjunkie_config['password']))
|
||||||
|
|
||||||
|
if r.status_code != 201:
|
||||||
|
print("Failed to submit package: {0}\n{1}".format(
|
||||||
|
r.status_code, r.text))
|
||||||
|
else:
|
||||||
|
print("The firmware has been successfuly published at Bintray.com!")
|
||||||
|
|
||||||
|
|
||||||
|
# Custom upload command and program name
|
||||||
|
env.Replace(
|
||||||
|
PROGNAME="firmware_v_%s" % version,
|
||||||
|
UPLOADCMD=publish_files
|
||||||
|
)
|
|
@ -0,0 +1,68 @@
|
||||||
|
# Copyright (c) 2019-present Dirk Jahnke (dirk.jahnke@mailbox.org)
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from os.path import basename
|
||||||
|
from platformio import util
|
||||||
|
|
||||||
|
Import('env')
|
||||||
|
|
||||||
|
project_config = util.load_project_config()
|
||||||
|
iotjunkie_config = {k: v for k, v in project_config.items("iotjunkie")}
|
||||||
|
version = project_config.get("common", "app_version")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Push new firmware to the iojunkie storage using API
|
||||||
|
#
|
||||||
|
print("======== Publish firmware")
|
||||||
|
print("Script does not do anything for now")
|
||||||
|
|
||||||
|
def publish_firmware(source, target, env):
|
||||||
|
firmware_path = str(source[0])
|
||||||
|
firmware_name = basename(firmware_path)
|
||||||
|
|
||||||
|
print("Uploading {0} to IOTJunkie. Version: {1}".format(
|
||||||
|
firmware_name, version))
|
||||||
|
|
||||||
|
url = "/".join([
|
||||||
|
"https://api.iotjunkie.org", "content",
|
||||||
|
iotjunkie_config.get("user"),
|
||||||
|
iotjunkie_config.get("repository"),
|
||||||
|
version, firmware_name
|
||||||
|
])
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Content-type": "application/octet-stream",
|
||||||
|
"X-IOTJunkie-Publish": "1",
|
||||||
|
"X-IOTJunkie-Override": "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
r = requests.put(
|
||||||
|
url,
|
||||||
|
data=open(firmware_path, "rb"),
|
||||||
|
headers=headers,
|
||||||
|
auth=(iotjunkie_config.get("user"), iotjunkie_config['password']))
|
||||||
|
|
||||||
|
if r.status_code != 201:
|
||||||
|
print("Failed to submit package: {0}\n{1}".format(
|
||||||
|
r.status_code, r.text))
|
||||||
|
else:
|
||||||
|
print("The firmware has been successfuly published at Bintray.com!")
|
||||||
|
|
||||||
|
|
||||||
|
# Custom upload command and program name
|
||||||
|
env.Replace(
|
||||||
|
PROGNAME="firmware_v_%s" % version,
|
||||||
|
UPLOADCMD=publish_firmware
|
||||||
|
)
|
|
@ -50,7 +50,7 @@ void Display::begin() {
|
||||||
P.begin();
|
P.begin();
|
||||||
// P.setZoneEffect(0, true, PA_FLIP_LR);
|
// P.setZoneEffect(0, true, PA_FLIP_LR);
|
||||||
graphicDisplay = P.getGraphicObject();
|
graphicDisplay = P.getGraphicObject();
|
||||||
E.begin(graphicDisplay);
|
E.begin(graphicDisplay, 1); // start at 2nd module, count starts with 0
|
||||||
|
|
||||||
P.setIntensity(1);
|
P.setIntensity(1);
|
||||||
for (charCode=1; charCode<=9; ++charCode) {
|
for (charCode=1; charCode<=9; ++charCode) {
|
||||||
|
@ -59,7 +59,7 @@ void Display::begin() {
|
||||||
// replace the 0 characters, we do not like the "slash"
|
// replace the 0 characters, we do not like the "slash"
|
||||||
P.addChar('0', newZero);
|
P.addChar('0', newZero);
|
||||||
|
|
||||||
char intro[] = {':', '-', ')', ' ', 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00};
|
char intro[] = {' ', 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00};
|
||||||
P.print(intro);
|
P.print(intro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
#include "FSUpdater.h"
|
||||||
|
#include <ESP8266HTTPClient.h>
|
||||||
|
#include <FS.h>
|
||||||
|
|
||||||
|
|
||||||
|
void FSUpdater::freeMemory() {
|
||||||
|
/*
|
||||||
|
if (bom != NULL) free(bom);
|
||||||
|
bom = NULL;
|
||||||
|
*/
|
||||||
|
if (bomBuffer != NULL) free(bomBuffer);
|
||||||
|
bomBuffer = NULL;
|
||||||
|
bomCounter = 0;
|
||||||
|
errorMessage = String();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSUpdater::manageFsOtaBom(String payload) {
|
||||||
|
freeMemory();
|
||||||
|
//bom = malloc(sizeof(BomEntry) * MAX_FILES);
|
||||||
|
bomBuffer = (char *) malloc(payload.length()+1);
|
||||||
|
payload.toCharArray(bomBuffer, payload.length()+1);
|
||||||
|
memset(bom, sizeof(BomEntry) * MAX_FILES_IN_BOM, 0);
|
||||||
|
|
||||||
|
char *parsePtr = bomBuffer; // to start
|
||||||
|
while (*parsePtr != 0) {
|
||||||
|
bom[bomCounter].executionMark = *parsePtr;
|
||||||
|
if (*parsePtr != ':') { errorMessage = String("Wrong seperation character ") + String(*parsePtr) + " at line " + String(bomCounter+1); return; }
|
||||||
|
++parsePtr;
|
||||||
|
|
||||||
|
bom[bomCounter].localFilename = parsePtr;
|
||||||
|
while (*parsePtr != ':' && *parsePtr != 0) ++parsePtr;
|
||||||
|
*parsePtr++ = 0; // End of string for localFilename
|
||||||
|
|
||||||
|
char *size_string = parsePtr;
|
||||||
|
while (*parsePtr != ':' && *parsePtr != 0) ++parsePtr;
|
||||||
|
*parsePtr++ = 0; // End of string for localFilename
|
||||||
|
bom[bomCounter].filesize = atol(size_string);
|
||||||
|
|
||||||
|
bom[bomCounter].md5 = parsePtr;
|
||||||
|
while (*parsePtr != ':' && *parsePtr != 0) ++parsePtr;
|
||||||
|
*parsePtr++ = 0; // End of string for localFilename
|
||||||
|
|
||||||
|
bom[bomCounter].remoteFilename = parsePtr;
|
||||||
|
while (*parsePtr != ':' && *parsePtr != 0 && *parsePtr != '\n' && *parsePtr != '\r') ++parsePtr;
|
||||||
|
*parsePtr++ = 0; // End of string for localFilename
|
||||||
|
|
||||||
|
// skip trailing characters if these are seperators or end of line
|
||||||
|
while (*parsePtr == ':' || *parsePtr == '\n' || *parsePtr == '\r' || *parsePtr == ' ') ++parsePtr;
|
||||||
|
++bomCounter;
|
||||||
|
if (bomCounter != MAX_FILES_IN_BOM) { errorMessage = "Too many files in BOM, max=" + String(MAX_FILES_IN_BOM); return; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSUpdater::checkForUpdates() {
|
||||||
|
HTTPClient http;
|
||||||
|
|
||||||
|
//http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
|
||||||
|
http.begin(baseUrl + "/" + swVersion + "/bom"); //HTTP
|
||||||
|
Serial.printf("[HTTP] GET %s/%s/bom", baseUrl.c_str(), swVersion.c_str());
|
||||||
|
// start connection and send HTTP header
|
||||||
|
int httpCode = http.GET();
|
||||||
|
|
||||||
|
// httpCode will be negative on error
|
||||||
|
if (httpCode > 0) {
|
||||||
|
if (httpCode == HTTP_CODE_OK) {
|
||||||
|
String payload = http.getString();
|
||||||
|
manageFsOtaBom(payload);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
http.end();
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef FSUpdater_h_included
|
||||||
|
#define FSUpdater_h_included
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#define MAX_FILES_IN_BOM 20
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *localFilename, *remoteFilename, *md5;
|
||||||
|
unsigned long filesize;
|
||||||
|
char executionMark;
|
||||||
|
} BomEntry;
|
||||||
|
|
||||||
|
class FSUpdater {
|
||||||
|
public:
|
||||||
|
FSUpdater(String _baseUrl, String currentVersion, String user, String password):
|
||||||
|
baseUrl(_baseUrl),
|
||||||
|
swVersion(currentVersion),
|
||||||
|
authUser(user),
|
||||||
|
authPassword(password) {};
|
||||||
|
void checkForUpdates();
|
||||||
|
void manageFsOtaBom(String payload);
|
||||||
|
void freeMemory();
|
||||||
|
boolean errorWhileParsingBom() { return (errorMessage.length() > 0); };
|
||||||
|
String getBomParsingError() { return errorMessage; };
|
||||||
|
unsigned int numberOfBomEntries() { return bomCounter; };
|
||||||
|
BomEntry *getBomEntry(unsigned int num) { return &bom[num]; };
|
||||||
|
protected:
|
||||||
|
String baseUrl;
|
||||||
|
String swVersion;
|
||||||
|
String authUser, authPassword;
|
||||||
|
BomEntry bom[MAX_FILES_IN_BOM]; // array of bom's, dynamically allocated
|
||||||
|
char *bomBuffer = NULL;
|
||||||
|
unsigned int bomCounter = 0;
|
||||||
|
String errorMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -14,18 +14,12 @@
|
||||||
#define PRINTX(s, v)
|
#define PRINTX(s, v)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MD_RobotEyes::MD_RobotEyes(void) :
|
|
||||||
_nextEmotion(E_NEUTRAL), _animState(S_IDLE),
|
|
||||||
_autoBlink(true), _timeBlinkMinimum(5000)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
void MD_RobotEyes::loadEye(uint8_t module, uint8_t ch)
|
void MD_RobotEyes::loadEye(uint8_t module, uint8_t ch)
|
||||||
{
|
{
|
||||||
uint8_t buf[EYE_COL_SIZE];
|
uint8_t buf[EYE_COL_SIZE];
|
||||||
uint8_t size;
|
|
||||||
|
|
||||||
size = _M->getChar(ch, EYE_COL_SIZE, buf);
|
_M->getChar(ch, EYE_COL_SIZE, buf);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < EYE_COL_SIZE; i++)
|
for (uint8_t i = 0; i < EYE_COL_SIZE; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,7 +62,9 @@ public:
|
||||||
*
|
*
|
||||||
* Instantiate a new instance of the class.
|
* Instantiate a new instance of the class.
|
||||||
*/
|
*/
|
||||||
MD_RobotEyes(void);
|
MD_RobotEyes(void):
|
||||||
|
_timeBlinkMinimum(5000), _animState(S_IDLE), _autoBlink(true), _nextEmotion(E_NEUTRAL)
|
||||||
|
{};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Destructor.
|
* Class Destructor.
|
||||||
|
|
67
src/main.cpp
67
src/main.cpp
|
@ -1,8 +1,13 @@
|
||||||
/* Wemos8266RelaysLedDisplay/main.cpp
|
/* Wemos8266RelaysLedDisplay/main.cpp
|
||||||
|
* (C) Dirk Jahnke <dirk.jahnke@mailbox.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define COMPDATE __DATE__ __TIME__
|
#define COMPDATE __DATE__ __TIME__
|
||||||
#define APP_VERSION "0.2.18"
|
// Following defines are set by build environment using -D parameter
|
||||||
|
// #define APP_VERSION "0.2.18"
|
||||||
|
// #define FS_UPDATE_BASE_URL "http://ota.iotjunkie.org/fc_client"
|
||||||
|
// #define FS_UPDATE_AUTH_USER "fcclient"
|
||||||
|
// #define FS_UPDATE_AUTH_PASSWORD "63Gs59PWveT6uQSh"
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <IOTAppStory.h>
|
#include <IOTAppStory.h>
|
||||||
|
@ -15,11 +20,12 @@
|
||||||
#include "Relays.h"
|
#include "Relays.h"
|
||||||
#include "Clock.h"
|
#include "Clock.h"
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
|
#include "FSUpdater.h"
|
||||||
|
|
||||||
// Button pin on the esp for selecting modes. 0 for Generic devices!
|
// Button pin on the esp for selecting modes. 0 for Generic devices!
|
||||||
#define MODEBUTTON D3
|
#define MODEBUTTON D3
|
||||||
#define RELAY1_PIN D1
|
//#define RELAY1_PIN D1
|
||||||
#define RELAY2_PIN D2
|
//#define RELAY2_PIN D2
|
||||||
#define DEBUG_RELAYS false
|
#define DEBUG_RELAYS false
|
||||||
#define DEBUG_DISPLAY false
|
#define DEBUG_DISPLAY false
|
||||||
#define STARTUP1_ANIMATION_DURATION_ms 2000
|
#define STARTUP1_ANIMATION_DURATION_ms 2000
|
||||||
|
@ -38,21 +44,36 @@ Display D(&realTime, &modelTime);
|
||||||
|
|
||||||
WiFiUDP ntpUDP;
|
WiFiUDP ntpUDP;
|
||||||
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
|
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
|
||||||
|
FSUpdater fsUpdater(FS_UPDATE_BASE_URL, APP_VERSION, FS_UPDATE_AUTH_USER, FS_UPDATE_AUTH_PASSWORD);
|
||||||
|
|
||||||
#define mkstring(x) #x
|
#define mkstring(x) #x
|
||||||
|
|
||||||
// Field default values
|
// Field default values
|
||||||
char *clockName = "FREMO";
|
#define CLOCK_NAME_LEN 8
|
||||||
char *clockSpeed_modelMsPerRealSec_String = "250";
|
#define CLOCK_SPEED_LEN 4
|
||||||
char *relay1Pin_String = mkstring(RELAY1_PIN);
|
#define RELAY_PIN_LEN 2
|
||||||
char *relay2Pin_String = mkstring(RELAY2_PIN);
|
#define RELAY_TIMING_LEN 3
|
||||||
int relay1Pin = RELAY1_PIN, relay2Pin = RELAY2_PIN;
|
#define CLOCK_NAME_DISPLAY_TIMING_LEN 5
|
||||||
char *relayHoldTime_ms_String = "200";
|
static char def_clockName[CLOCK_NAME_LEN+1] = "FREMO";
|
||||||
char *relayMinOffTime_ms_String = "100";
|
static char def_clockSpeed_modelMsPerRealSec_String[CLOCK_SPEED_LEN+1] = "250";
|
||||||
|
static char def_relay1Pin_String[RELAY_PIN_LEN+1] = mkstring(D1);
|
||||||
|
static char def_relay2Pin_String[RELAY_PIN_LEN+1] = mkstring(D2);
|
||||||
|
static int relay1Pin = D1, relay2Pin = D2;
|
||||||
|
static char def_relayHoldTime_ms_String[RELAY_TIMING_LEN+1] = "200";
|
||||||
|
static char def_relayMinOffTime_ms_String[RELAY_TIMING_LEN+1] = "100";
|
||||||
// Clock Display Config Parameter
|
// Clock Display Config Parameter
|
||||||
static char * displayClockNameEvery_ms_String = "16000";
|
static char def_displayClockNameEvery_ms_String[CLOCK_NAME_DISPLAY_TIMING_LEN+1] = "16000";
|
||||||
static char * displayClockNameDuration_ms_String = "1200";
|
static char def_displayClockNameDuration_ms_String[CLOCK_NAME_DISPLAY_TIMING_LEN+1] = "1200";
|
||||||
|
|
||||||
|
static char *clockName = def_clockName;
|
||||||
|
static char *clockSpeed_modelMsPerRealSec_String = def_clockSpeed_modelMsPerRealSec_String;
|
||||||
|
static char *relay1Pin_String = def_relay1Pin_String;
|
||||||
|
static char *relay2Pin_String = def_relay2Pin_String;
|
||||||
|
static char *relayHoldTime_ms_String = def_relayHoldTime_ms_String;
|
||||||
|
static char *relayMinOffTime_ms_String = def_relayMinOffTime_ms_String;
|
||||||
|
static char *displayClockNameEvery_ms_String = def_displayClockNameEvery_ms_String;
|
||||||
|
static char *displayClockNameDuration_ms_String = def_displayClockNameDuration_ms_String;
|
||||||
|
|
||||||
|
|
||||||
void setupIAS(void) {
|
void setupIAS(void) {
|
||||||
#if defined ESP8266
|
#if defined ESP8266
|
||||||
|
@ -69,14 +90,14 @@ void setupIAS(void) {
|
||||||
IAS.preSetAutoUpdate(true);
|
IAS.preSetAutoUpdate(true);
|
||||||
|
|
||||||
// define fields
|
// define fields
|
||||||
IAS.addField(clockName, "Clock Name", 8, 'T');
|
IAS.addField(clockName, "Clock Name", CLOCK_NAME_LEN, 'T');
|
||||||
IAS.addField(clockSpeed_modelMsPerRealSec_String, "Model MilliSec per Real Sec", 8, 'N');
|
IAS.addField(clockSpeed_modelMsPerRealSec_String, "Model MilliSec per Real Sec", CLOCK_SPEED_LEN, 'N');
|
||||||
IAS.addField(displayClockNameEvery_ms_String, "Display clock name every (ms)", 5, 'N');
|
IAS.addField(displayClockNameEvery_ms_String, "Display clock name every (ms)", CLOCK_NAME_DISPLAY_TIMING_LEN, 'N');
|
||||||
IAS.addField(displayClockNameDuration_ms_String, "Display clock name duration (ms)", 5, 'N');
|
IAS.addField(displayClockNameDuration_ms_String, "Display clock name duration (ms)", CLOCK_NAME_DISPLAY_TIMING_LEN, 'N');
|
||||||
IAS.addField(relay1Pin_String, "Pin Relay 1", 2, 'P');
|
IAS.addField(relay1Pin_String, "Pin Relay 1", RELAY_PIN_LEN, 'P');
|
||||||
IAS.addField(relay2Pin_String, "Pin Relay 2", 2, 'P');
|
IAS.addField(relay2Pin_String, "Pin Relay 2", RELAY_PIN_LEN, 'P');
|
||||||
IAS.addField(relayHoldTime_ms_String, "Relay hold time (ms)", 3, 'N');
|
IAS.addField(relayHoldTime_ms_String, "Relay hold time (ms)", RELAY_TIMING_LEN, 'N');
|
||||||
IAS.addField(relayMinOffTime_ms_String, "Relay min off time (ms)", 3, 'N');
|
IAS.addField(relayMinOffTime_ms_String, "Relay min off time (ms)", RELAY_TIMING_LEN, 'N');
|
||||||
|
|
||||||
IAS.onModeButtonShortPress([]() {
|
IAS.onModeButtonShortPress([]() {
|
||||||
Serial.println(F(" If mode button is released, I will enter firmware update mode."));
|
Serial.println(F(" If mode button is released, I will enter firmware update mode."));
|
||||||
|
@ -176,7 +197,7 @@ static unsigned long lastTimeOutput_ms = 0;
|
||||||
|
|
||||||
void loop(void)
|
void loop(void)
|
||||||
{
|
{
|
||||||
static int lastMinutes = 0;
|
static unsigned int lastMinutes = 0;
|
||||||
|
|
||||||
static unsigned long firstLoop_ts = 0;
|
static unsigned long firstLoop_ts = 0;
|
||||||
if (firstLoop_ts == 0) firstLoop_ts = millis();
|
if (firstLoop_ts == 0) firstLoop_ts = millis();
|
||||||
|
@ -213,7 +234,7 @@ void loop(void)
|
||||||
|
|
||||||
D.loop();
|
D.loop();
|
||||||
|
|
||||||
// toggle relays
|
// toggle relays on minute change
|
||||||
if (lastMinutes != realTime.getMinutes()) {
|
if (lastMinutes != realTime.getMinutes()) {
|
||||||
R.toggle();
|
R.toggle();
|
||||||
lastMinutes = realTime.getMinutes();
|
lastMinutes = realTime.getMinutes();
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
manifest.json.gz
|
||||||
|
main.css.gz
|
||||||
|
fremoei.gif.gz
|
||||||
|
img_fremo_sw.gif.gz
|
||||||
|
index.htm.gz
|
||||||
|
led-on.png.gz
|
||||||
|
led-off.png.gz
|
||||||
|
img_sh.gif.gz
|
||||||
|
btn-do.png.gz
|
||||||
|
btn.png.gz
|
||||||
|
favicon.ico.gz
|
Loading…
Reference in New Issue