Compare commits

..

No commits in common. "74a7a1e3a33f29bb9a0652c9a58265352567e746" and "114b76d19005236aecc31916a3f57dac7ee267b8" have entirely different histories.

16 changed files with 86 additions and 219 deletions

15
.vscode/arduino.json vendored
View file

@ -1,15 +0,0 @@
{
"configuration": "xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,eesz=4M2M,led=2,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=460800",
"board": "esp8266:esp8266:nodemcuv2",
"port": "/dev/tty.usbserial-110",
"programmer": "AVRISP mkII",
"sketch": "firmware/firmware.ino",
"includePath": [
"/Users/klaute/Documents/Arduino/libraries",
"/Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include",
"/Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/lib",
"/Applications/Arduino.app//Contents/Java/hardware/arduino/avr/libraries"
"/Applications/Arduino.app/Contents/Java/hardware/tools/avr/include",
"/Applications/Arduino.app/Contents/Java/hardware/tools/avr/x86_64-apple-darwin16.1.0/avr/include"
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 MiB

After

Width:  |  Height:  |  Size: 2 MiB

View file

@ -1,6 +1,4 @@
#define VERSION_STR "2.0.0"
#define USE_STATIC_IP //! uncomment to enable Static IP Adress
#define SERIAL_BAUD_RATE 115200
@ -9,8 +7,7 @@
//#define DEVELOPMENT
#define LIGHT_NAME "Lumini/Lominie Pixie30/P30 light control" // default light name
#define LIGHT_NAME_DEV_POSTFIX " (DEV)"
#define LIGHT_NAME_STR "Lumini/Lominie Pixie30/P30 light control" // default light name
#define LIGHTS_COUNT 4 // do not modify because luminie p30 only has 4 channel, never set above 80
@ -20,10 +17,6 @@
#define EEPROM_DYNAMIC_IP_ADDRESS 3
#define EEPROM_LAST_STATE_ADDRESS 4 // the first "last state" information for the first light
#define EEPROM_TIMING_DATA_ADDRESS (EEPROM_LAST_STATE_ADDRESS + LIGHTS_COUNT) // Stored data date per light ELE_USED; HH; MM; CH1; CH2; CH3; CH4;
#define EEPROM_IP_ADDRESS (EEPROM_TIMING_DATA_ADDRESS + 60) // 10 blocks of 6 byte per timing control data block = 60 byte EEPROM space
#define EEPROM_GW_ADDRESS (EEPROM_IP_ADDRESS + 4) // step 4 byte further IP
#define EEPROM_NM_ADDRESS (EEPROM_GW_ADDRESS + 4) // step 4 byte further GW
#define EEPROM_DNS_ADDRESS (EEPROM_NM_ADDRESS + 4) // step 4 byte further NM
#define BRI_MOD_STEPS_PER_SEC 25

View file

@ -272,23 +272,15 @@ if (document.getElementById('tab-tde').classList.contains('visible')) {
loadTCGraphData();
}
}, 2000);
function updateLightStateAndPWMValues() {
console.log('----> setting bri, power switch, and pwm data <----');
const promises = [];
function updateLightState() {
console.log('----> setting bri and power switch <----');
for (let i = 1; i <= {{LIGHT_COUNT}}; i++) {
const lightURL = `http://{{IP_ADDRESS}}/state?light=${i}`;
promises.push(fetch(lightURL).then(response => response.json()));
}
Promise.all(promises)
.then(dataArray => {
for (let i = 1; i <= {{LIGHT_COUNT}}; i++) {
const data = dataArray[i - 1];
fetch(lightURL).then(response => response.json()).then(data => {
const briSlider = document.getElementById(`bri${i - 1}`);
const briSliderVal = document.getElementById(`bri${i - 1}_val`);
const onLinkOn = document.getElementById(`on${i - 1}_on`);
const onLinkOff = document.getElementById(`on${i - 1}_off`);
const pwmElement = document.getElementById(`light${i - 1}_pwm`);
const pwmElementTxt = document.getElementById(`light${i - 1}_pwm_txt`);
briSlider.value = data.bri;
briSliderVal.innerHTML = (Math.round((data.bri * 100.0 / 255.0) * 100) / 100).toFixed(2);
if (data.on == true) {
@ -298,18 +290,30 @@ onLinkOff.classList.remove('pure-button-primary');
onLinkOn.classList.remove('pure-button-primary');
onLinkOff.classList.add('pure-button-primary');
}
}).catch(error => console.error(error));
}
}
setInterval(updateLightState, 10000);
updateLightState();
function updatePWMValues() {
console.log('----> setting pwm data <----');
for (let i = 0; i < {{LIGHT_COUNT}}; i++) {
const lightID = i + 1;
const pwmElement = document.getElementById(`light${i}_pwm`);
const pwmElementTxt = document.getElementById(`light${i}_pwm_txt`);
if (pwmElement) {
const url = `http://{{IP_ADDRESS}}/state?light=${lightID}`;
fetch(url).then(response => response.json()).then(data => {
const pwmValue = ((Math.round((data.curpwm - ((data.curpwm >= {{PWM_MIN}}) ? {{PWM_MIN}} : 0)) / {{PWM_MAX}} * 10000) / 100).toFixed(2));
pwmElement.innerText = pwmValue.toString();
pwmElement.value = pwmValue;
pwmElementTxt.innerText = pwmValue.toString();
}).catch(error => console.error(error));
}
}
})
.catch(error => console.error(error));
}
updateLightStateAndPWMValues();
setInterval(updateLightStateAndPWMValues, 5000);
updatePWMValues();
setInterval(updatePWMValues, 5000);
var links = document.querySelectorAll('[id^="on"][id$="_off"]');
links.forEach(function(link) {
link.addEventListener('click', function(event) {
@ -350,7 +354,7 @@ console.log('Error while sending data to server.');
}
};
xhr.send();
updateLightStateAndPWMValues();
updateLightState();
this.classList.add('pure-button-primary');
document.getElementById('on'+id+'_on').classList.remove('pure-button-primary');
});
@ -395,7 +399,7 @@ console.log('Error while sending data to server.');
}
};
xhr.send();
updateLightStateAndPWMValues();
updateLightState();
this.classList.add('pure-button-primary');
document.getElementById('on'+id+'_off').classList.remove('pure-button-primary');
});

View file

@ -56,15 +56,15 @@
<input id="gwip" name="gwip" type="text" value="{{WIFI_CFG_GW}}">
</div>
<div class="pure-control-group">
<label for="netmask">Netmask</label>
<label for="ip">Netmask</label>
<input id="netmask" name="netmas" type="text" value="{{WIFI_CFG_NM}}">
</div>
<div class="pure-control-group">
<label for="dns">DNS</label>
<label for="ip">DNS</label>
<input id="netmask" name="dns" type="text" value="{{WIFI_CFG_DNS}}">
</div>
<div class="pure-controls">
<button type="dns" class="pure-button pure-button-primary">Save</button>
<button type="submit" class="pure-button pure-button-primary">Save</button>
</div>
</form>
</div><!-- end of config div -->

View file

@ -18,6 +18,7 @@
</td>
</tr>
</table>
<br>
<a href="#" id="save-button" class="pure-button pure-button-primary" onclick="sendDataToServer();">save</a>
</div>
</div> <!-- end of tab-tde -->
@ -25,6 +26,5 @@
</script>
</div>
</fieldset>
<p>{{VERSION_STR}}</p>
</body>
</html>

View file

@ -14,7 +14,7 @@
</head>
<body>
<fieldset>
<h3>{{LIGHT_NAME}}{{LIGHT_NAME_DEV_POSTFIX}}</h3>
<h3>{{LIGHT_NAME}}</h3>
<div class="toast"></div>
<div class="pure-form pure-form-aligned">
<div class="pure-controls">

View file

@ -13,6 +13,12 @@
//********* preprocessor block *********//
#ifdef DEVELOPMENT
#define LIGHT_NAME "Dimmable Hue Light (DEV)"
#else
#define LIGHT_NAME LIGHT_NAME_STR
#endif
//********* Config block *********//
// blue, warmwhite, purple, white&red&green
@ -33,7 +39,7 @@ IPAddress dns (192, 168, 0, 1);
//********************************//
#define LIGHT_VERSION 2.1 // diyHue light version
#define LIGHT_VERSION 2.1
#define LAST_STATE_STARTUP_LIGHT_LAST_STATE 0
#define LAST_STATE_STARTUP_LIGHT_ON_STATE 1
@ -97,13 +103,13 @@ void setup()
Serial.printf("Datei Name: %s, Größe: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
}
read_eeprom_config();
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) == 0)
{ // static ip is used
{
WiFi.config(strip_ip, gateway_ip, subnet_mask, dns);
}
read_eeprom_config();
for (int j = 0; j < 200; j++)
{
lightEngine();
@ -254,49 +260,6 @@ void read_eeprom_config()
Serial.println("light[" + (String)light + "] = " + (String)light_state[light]);
}
// read IP, NetMask, GateWay and DNS from EEPROM or store default value
// only IPv4 is supported
if (EEPROM.read(EEPROM_IP_ADDRESS) == 255)
{
for (uint8_t i = 0; i < 4; i++)
{
EEPROM.write(EEPROM_IP_ADDRESS + i, strip_ip[i]);
EEPROM.write(EEPROM_GW_ADDRESS + i, gateway_ip[i]);
EEPROM.write(EEPROM_NM_ADDRESS + i, subnet_mask[i]);
EEPROM.write(EEPROM_DNS_ADDRESS + i, dns[i]);
}
} else {
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) == 0)
{
for (uint8_t i = 0; i < 4; i++)
{
strip_ip[i] = EEPROM.read(EEPROM_IP_ADDRESS + i);
gateway_ip[i] = EEPROM.read(EEPROM_GW_ADDRESS + i);
subnet_mask[i] = EEPROM.read(EEPROM_NM_ADDRESS + i);
dns[i] = EEPROM.read(EEPROM_DNS_ADDRESS + i);
}
Serial.println("IP from EEPROM: " +
(String)strip_ip[0] + "." +
(String)strip_ip[1] + "." +
(String)strip_ip[2] + "." +
(String)strip_ip[3]);
Serial.println("GW from EEPROM: " +
(String)gateway_ip[0] + "." +
(String)gateway_ip[1] + "." +
(String)gateway_ip[2] + "." +
(String)gateway_ip[3]);
Serial.println("NetMask from EEPROM: " +
(String)subnet_mask[0] + "." +
(String)subnet_mask[1] + "." +
(String)subnet_mask[2] + "." +
(String)subnet_mask[3]);
Serial.println("DNS from EEPROM: " +
(String)dns[0] + "." +
(String)dns[1] + "." +
(String)dns[2] + "." +
(String)dns[3]);
}
}
}
//********************************//

View file

@ -317,49 +317,50 @@ setInterval(function() {
}
}, 2000);
function updateLightStateAndPWMValues() {
console.log('----> setting bri, power switch, and pwm data <----');
const promises = [];
function updateLightState() {
console.log('----> setting bri and power switch <----');
for (let i = 1; i <= {{LIGHT_COUNT}}; i++) {
const lightURL = `http://{{IP_ADDRESS}}/state?light=${i}`;
promises.push(fetch(lightURL).then(response => response.json()));
}
Promise.all(promises)
.then(dataArray => {
for (let i = 1; i <= {{LIGHT_COUNT}}; i++) {
const data = dataArray[i - 1];
const briSlider = document.getElementById(`bri${i - 1}`);
const briSliderVal = document.getElementById(`bri${i - 1}_val`);
const onLinkOn = document.getElementById(`on${i - 1}_on`);
const onLinkOff = document.getElementById(`on${i - 1}_off`);
const pwmElement = document.getElementById(`light${i - 1}_pwm`);
const pwmElementTxt = document.getElementById(`light${i - 1}_pwm_txt`);
briSlider.value = data.bri;
briSliderVal.innerHTML = (Math.round((data.bri * 100.0 / 255.0) * 100) / 100).toFixed(2);
if (data.on == true) {
onLinkOn.classList.add('pure-button-primary');
onLinkOff.classList.remove('pure-button-primary');
} else {
onLinkOn.classList.remove('pure-button-primary');
onLinkOff.classList.add('pure-button-primary');
}
if (pwmElement) {
const pwmValue = ((Math.round((data.curpwm - ((data.curpwm >= {{PWM_MIN}}) ? {{PWM_MIN}} : 0)) / {{PWM_MAX}} * 10000) / 100).toFixed(2));
pwmElement.innerText = pwmValue.toString();
pwmElement.value = pwmValue;
pwmElementTxt.innerText = pwmValue.toString();
}
fetch(lightURL).then(response => response.json()).then(data => {
const briSlider = document.getElementById(`bri${i - 1}`);
const briSliderVal = document.getElementById(`bri${i - 1}_val`);
const onLinkOn = document.getElementById(`on${i - 1}_on`);
const onLinkOff = document.getElementById(`on${i - 1}_off`);
briSlider.value = data.bri;
briSliderVal.innerHTML = (Math.round((data.bri * 100.0 / 255.0) * 100) / 100).toFixed(2);
if (data.on == true) {
onLinkOn.classList.add('pure-button-primary');
onLinkOff.classList.remove('pure-button-primary');
} else {
onLinkOn.classList.remove('pure-button-primary');
onLinkOff.classList.add('pure-button-primary');
}
})
.catch(error => console.error(error));
}).catch(error => console.error(error));
}
}
setInterval(updateLightState, 10000);
updateLightState();
updateLightStateAndPWMValues();
setInterval(updateLightStateAndPWMValues, 5000);
function updatePWMValues() {
console.log('----> setting pwm data <----');
for (let i = 0; i < {{LIGHT_COUNT}}; i++) {
const lightID = i + 1;
const pwmElement = document.getElementById(`light${i}_pwm`);
const pwmElementTxt = document.getElementById(`light${i}_pwm_txt`);
if (pwmElement) {
const url = `http://{{IP_ADDRESS}}/state?light=${lightID}`;
fetch(url).then(response => response.json()).then(data => {
const pwmValue = ((Math.round((data.curpwm - ((data.curpwm >= {{PWM_MIN}}) ? {{PWM_MIN}} : 0)) / {{PWM_MAX}} * 10000) / 100).toFixed(2));
//console.log('curpwm[' + i + '] = ' + data.curpwm + ' = ' + pwmValue);
pwmElement.innerText = pwmValue.toString();
pwmElement.value = pwmValue;
pwmElementTxt.innerText = pwmValue.toString();
}).catch(error => console.error(error));
}
}
}
updatePWMValues();
setInterval(updatePWMValues, 5000);
// Suche nach allen Links auf der Seite mit IDs von on0_off bis on3_off
var links = document.querySelectorAll('[id^="on"][id$="_off"]');
@ -409,7 +410,7 @@ links.forEach(function(link) {
// Sende die Anfrage im Hintergrund
xhr.send();
updateLightStateAndPWMValues();
updateLightState();
this.classList.add('pure-button-primary');
document.getElementById('on'+id+'_on').classList.remove('pure-button-primary');
});
@ -462,7 +463,7 @@ links.forEach(function(link) {
// Sende die Anfrage im Hintergrund
xhr.send();
updateLightStateAndPWMValues();
updateLightState();
this.classList.add('pure-button-primary');
document.getElementById('on'+id+'_off').classList.remove('pure-button-primary');
});

View file

@ -56,15 +56,15 @@
<input id="gwip" name="gwip" type="text" value="{{WIFI_CFG_GW}}">
</div>
<div class="pure-control-group">
<label for="netmask">Netmask</label>
<label for="ip">Netmask</label>
<input id="netmask" name="netmas" type="text" value="{{WIFI_CFG_NM}}">
</div>
<div class="pure-control-group">
<label for="dns">DNS</label>
<label for="ip">DNS</label>
<input id="netmask" name="dns" type="text" value="{{WIFI_CFG_DNS}}">
</div>
<div class="pure-controls">
<button type="dns" class="pure-button pure-button-primary">Save</button>
<button type="submit" class="pure-button pure-button-primary">Save</button>
</div>
</form>
</div><!-- end of config div -->

View file

@ -19,6 +19,7 @@
</tr>
</table>
<br>
<a href="#" id="save-button" class="pure-button pure-button-primary" onclick="sendDataToServer();">save</a>
</div>
</div> <!-- end of tab-tde -->
@ -28,6 +29,5 @@
</div>
</fieldset>
<p>{{VERSION_STR}}</p>
</body>
</html>

View file

@ -14,7 +14,7 @@
</head>
<body>
<fieldset>
<h3>{{LIGHT_NAME}}{{LIGHT_NAME_DEV_POSTFIX}}</h3>
<h3>{{LIGHT_NAME}}</h3>
<div class="toast"></div>
<div class="pure-form pure-form-aligned">
<div class="pure-controls">

View file

@ -23,9 +23,9 @@
bool tc_testOngoing = false;
uint32_t tc_last_check = TIME_CHECK_INTERVAL_MS; // initially check if new data needs to be read
uint32_t tc_last_check = 60000;
uint8_t current_target_data_block = 255; // no data processed yet
uint8_t current_target_data_block = 255;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, MY_NTP_SERVER);

View file

@ -286,8 +286,7 @@ void init_webserver()
}
}
if (server.hasArg("dip"))
{
if (server.hasArg("dip")) {
uint8_t tmp = EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS);
uint8_t tmp2 = (server.arg("dip") == "true" ? 1 : 0);
if (tmp != tmp2)
@ -299,78 +298,6 @@ void init_webserver()
}
}
if (server.hasArg("ip"))
{
strip_ip.fromString(server.arg("ip"));
// make it persistent to eeprom
EEPROM.write(EEPROM_IP_ADDRESS, strip_ip[0]);
EEPROM.write(EEPROM_IP_ADDRESS+1, strip_ip[1]);
EEPROM.write(EEPROM_IP_ADDRESS+2, strip_ip[2]);
EEPROM.write(EEPROM_IP_ADDRESS+3, strip_ip[3]);
EEPROM.commit();
Serial.println("IP set to: " +
(String)EEPROM.read(EEPROM_IP_ADDRESS) + "." +
(String)EEPROM.read(EEPROM_IP_ADDRESS+1) + "." +
(String)EEPROM.read(EEPROM_IP_ADDRESS+2) + "." +
(String)EEPROM.read(EEPROM_IP_ADDRESS+3));
}
if (server.hasArg("gwip"))
{
gateway_ip.fromString(server.arg("gwip"));
// make it persistent to eeprom
EEPROM.write(EEPROM_GW_ADDRESS, gateway_ip[0]);
EEPROM.write(EEPROM_GW_ADDRESS+1, gateway_ip[1]);
EEPROM.write(EEPROM_GW_ADDRESS+2, gateway_ip[2]);
EEPROM.write(EEPROM_GW_ADDRESS+3, gateway_ip[3]);
EEPROM.commit();
Serial.println("GW set to: " +
(String)EEPROM.read(EEPROM_GW_ADDRESS) + "." +
(String)EEPROM.read(EEPROM_GW_ADDRESS+1) + "." +
(String)EEPROM.read(EEPROM_GW_ADDRESS+2) + "." +
(String)EEPROM.read(EEPROM_GW_ADDRESS+3));
}
if (server.hasArg("netmas"))
{
subnet_mask.fromString(server.arg("netmas"));
// make it persistent to eeprom
EEPROM.write(EEPROM_NM_ADDRESS, subnet_mask[0]);
EEPROM.write(EEPROM_NM_ADDRESS+1, subnet_mask[1]);
EEPROM.write(EEPROM_NM_ADDRESS+2, subnet_mask[2]);
EEPROM.write(EEPROM_NM_ADDRESS+3, subnet_mask[3]);
EEPROM.commit();
Serial.println("NetMask set to: " +
(String)EEPROM.read(EEPROM_NM_ADDRESS) + "." +
(String)EEPROM.read(EEPROM_NM_ADDRESS+1) + "." +
(String)EEPROM.read(EEPROM_NM_ADDRESS+2) + "." +
(String)EEPROM.read(EEPROM_NM_ADDRESS+3));
}
if (server.hasArg("dns"))
{
dns.fromString(server.arg("dns"));
// make it persistent to eeprom
EEPROM.write(EEPROM_DNS_ADDRESS, dns[0]);
EEPROM.write(EEPROM_DNS_ADDRESS+1, dns[1]);
EEPROM.write(EEPROM_DNS_ADDRESS+2, dns[2]);
EEPROM.write(EEPROM_DNS_ADDRESS+3, dns[3]);
EEPROM.commit();
Serial.println("DNS set to: " +
(String)EEPROM.read(EEPROM_DNS_ADDRESS) + "." +
(String)EEPROM.read(EEPROM_DNS_ADDRESS+1) + "." +
(String)EEPROM.read(EEPROM_DNS_ADDRESS+2) + "." +
(String)EEPROM.read(EEPROM_DNS_ADDRESS+3));
}
// process the received data for every light
for (int light = 0; light < LIGHTS_COUNT; light++)
{
@ -534,13 +461,7 @@ String genLightControlHTML()
String replacePlaceholder(String http_content)
{
http_content.replace("{{VERSION_STR}}", (String)VERSION_STR);
http_content.replace("{{LIGHT_NAME}}", (String)LIGHT_NAME);
#ifdef DEVELOPMENT
http_content.replace("{{LIGHT_NAME_DEV_POSTFIX}}", (String)LIGHT_NAME_DEV_POSTFIX);
#else
http_content.replace("{{LIGHT_NAME_DEV_POSTFIX}}", (String)"&nbsp;");
#endif
http_content.replace("{{LIGHT_COUNT}}", (String)LIGHTS_COUNT);