mirror of https://github.com/arendst/Tasmota.git
Add Sonoff B1 Support. AiLight is experimental
This commit is contained in:
parent
5fdc5e890a
commit
99c9b1671c
|
@ -1,7 +1,9 @@
|
|||
/* 5.5.2f
|
||||
/* 5.5.2g
|
||||
* Fix Sonoff Pow intermittent exception 0
|
||||
* Change Sonoff Pow sending Domoticz telemetry data only
|
||||
* Add Ai-Thinker RGBW led (AiLight) and Sonoff B1 support (experimental)
|
||||
* Add Sonoff B1 support
|
||||
* Add Ai-Thinker RGBW led (AiLight) (experimental)
|
||||
* Add NeoPixelBus library to Sonoff Led for Hue support (saves 1k1 code space)
|
||||
*
|
||||
* 5.5.2 20170808
|
||||
* Extent max number of WS2812 pixels from 256 to 512 (#667)
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
|
||||
====================================================*/
|
||||
|
||||
#define VERSION 0x05050206 // 5.5.2f
|
||||
#define VERSION 0x05050207 // 5.5.2g
|
||||
|
||||
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
|
||||
enum week_t {Last, First, Second, Third, Fourth};
|
||||
|
@ -172,6 +172,7 @@ enum opt_t {P_HOLD_TIME, P_MAX_POWER_RETRY, P_MAX_PARAM8}; // Index in sysCf
|
|||
#include <ESP8266httpUpdate.h> // Ota
|
||||
#include <StreamString.h> // Webserver, Updater
|
||||
#include <ArduinoJson.h> // WemoHue, IRremote, Domoticz
|
||||
#include <NeoPixelBus.h> // Ws2812, Sonoff Led hue support
|
||||
#ifdef USE_WEBSERVER
|
||||
#include <ESP8266WebServer.h> // WifiManager, Webserver
|
||||
#include <DNSServer.h> // WifiManager
|
||||
|
|
|
@ -117,9 +117,9 @@ enum fpins_t {
|
|||
GPIO_HLW_CF1, // HLW8012 CF1 voltage / current (Sonoff Pow)
|
||||
GPIO_HLW_CF, // HLW8012 CF power (Sonoff Pow)
|
||||
GPIO_ADC0, // ADC
|
||||
GPIO_DI, // my92x1 PWM input
|
||||
GPIO_DCKI, // my92x1 CLK input
|
||||
GPIO_USER, // User configurable
|
||||
GPIO_DI, // my9231 PWM input
|
||||
GPIO_DCKI, // my9231 CLK input
|
||||
GPIO_MAX };
|
||||
|
||||
/********************************************************************************************/
|
||||
|
|
|
@ -80,7 +80,6 @@ void sl_my92x1_command(uint8_t chips, uint8_t command)
|
|||
{
|
||||
uint8_t command_data;
|
||||
|
||||
// ets_intr_lock();
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
// Send 12 DI pulse, after 6 pulse's falling edge store duty data, and 12
|
||||
// pulse's rising edge convert to command mode.
|
||||
|
@ -104,19 +103,17 @@ void sl_my92x1_command(uint8_t chips, uint8_t command)
|
|||
// at 16 pulse's falling edge convert to duty mode.
|
||||
sl_di_pulse(16);
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
// ets_intr_unlock();
|
||||
}
|
||||
|
||||
void sl_my9231_duty(uint16_t duty_r, uint16_t duty_g, uint16_t duty_b, uint16_t duty_w, uint16_t duty_c)
|
||||
void sl_my9231_duty(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b, uint8_t duty_w, uint8_t duty_c)
|
||||
{
|
||||
uint16_t duty_current = 0;
|
||||
uint8_t duty_current = 0;
|
||||
|
||||
uint16_t duty[6] = { duty_r, duty_g, duty_b, duty_w, duty_c, 0 }; // Definition for RGBWC channels
|
||||
uint8_t duty[6] = { duty_w, duty_c, 0, duty_g, duty_r, duty_b }; // Definition for RGBWC channels
|
||||
|
||||
// ets_intr_lock();
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
for (uint8_t channel = 0; channel < 6; channel++) { // RGBWC0 6CH
|
||||
duty_current = duty[channel]; // RGBWC Channel
|
||||
for (uint8_t channel = 0; channel < 6; channel++) { // WC0GRB 6CH
|
||||
duty_current = duty[channel];
|
||||
for (uint8_t i = 0; i < 4; i++) { // Send 8bit Data
|
||||
digitalWrite(sl_pdcki, LOW);
|
||||
digitalWrite(sl_pdi, (duty_current & 0x80));
|
||||
|
@ -131,16 +128,14 @@ void sl_my9231_duty(uint16_t duty_r, uint16_t duty_g, uint16_t duty_b, uint16_t
|
|||
os_delay_us(12); // TStart > 12us. Ready for send DI pulse.
|
||||
sl_di_pulse(8); // Send 8 DI pulse. After 8 pulse falling edge, store old data.
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
// ets_intr_unlock();
|
||||
}
|
||||
|
||||
void sl_my9291_duty(uint16_t duty_r, uint16_t duty_g, uint16_t duty_b, uint16_t duty_w)
|
||||
void sl_my9291_duty(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b, uint8_t duty_w)
|
||||
{
|
||||
uint16_t duty_current = 0;
|
||||
uint8_t duty_current = 0;
|
||||
|
||||
uint16_t duty[4] = { duty_r, duty_g, duty_b, duty_w }; // Definition for RGBW channels
|
||||
uint8_t duty[4] = { duty_r, duty_g, duty_b, duty_w }; // Definition for RGBW channels
|
||||
|
||||
// ets_intr_lock();
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
for (uint8_t channel = 0; channel < 4; channel++) { // RGBW 4CH
|
||||
duty_current = duty[channel]; // RGBW Channel
|
||||
|
@ -158,7 +153,6 @@ void sl_my9291_duty(uint16_t duty_r, uint16_t duty_g, uint16_t duty_b, uint16_t
|
|||
os_delay_us(12); // TStart > 12us. Ready for send DI pulse.
|
||||
sl_di_pulse(8); // Send 8 DI pulse. After 8 pulse falling edge, store old data.
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
// ets_intr_unlock();
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
@ -198,7 +192,7 @@ void sl_init(void)
|
|||
sl_my92x1_command(1, 0x18); // ONE_SHOT_DISABLE, REACTION_FAST, BIT_WIDTH_8, FREQUENCY_DIVIDE_1, SCATTER_APDM
|
||||
} else if (5 == sfl_flg) {
|
||||
// Clear all duty register
|
||||
sl_dcki_pulse(48); // 2 * 24 bits
|
||||
sl_dcki_pulse(64); // 2 * 32 bits
|
||||
sl_my92x1_command(2, 0x18); // ONE_SHOT_DISABLE, REACTION_FAST, BIT_WIDTH_8, FREQUENCY_DIVIDE_1, SCATTER_APDM
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +205,7 @@ void sl_init(void)
|
|||
void sl_setDim(uint8_t myDimmer)
|
||||
{
|
||||
float temp;
|
||||
|
||||
|
||||
if ((1 == sfl_flg) && (100 == myDimmer)) {
|
||||
myDimmer = 99; // BN-SZ01 starts flickering at dimmer = 100
|
||||
}
|
||||
|
@ -371,76 +365,17 @@ void sl_animate()
|
|||
|
||||
void sl_rgb2hsb(float *hue, float *sat, float *bri)
|
||||
{
|
||||
sl_setDim(sysCfg.led_dimmer[0]);
|
||||
RgbColor dcolor;
|
||||
|
||||
float r = (float)(sl_dcolor[0] / 255.0f);
|
||||
float g = (float)(sl_dcolor[1] / 255.0f);
|
||||
float b = (float)(sl_dcolor[2] / 255.0f);
|
||||
|
||||
float max = fmax(fmax(r, g), b);
|
||||
float min = fmin(fmin(r, g), b);
|
||||
|
||||
*bri = (max + min) / 2.0f;
|
||||
|
||||
if (max == min) {
|
||||
*hue = *sat = 0.0f;
|
||||
} else {
|
||||
float d = max - min;
|
||||
*sat = (*bri > 0.5f) ? d / (2.0f - max - min) : d / (max + min);
|
||||
|
||||
if (r > g && r > b) {
|
||||
*hue = (g - b) / d + (g < b ? 6.0f : 0.0f);
|
||||
}
|
||||
else if (g > b) {
|
||||
*hue = (b - r) / d + 2.0f;
|
||||
}
|
||||
else {
|
||||
*hue = (r - g) / d + 4.0f;
|
||||
}
|
||||
*hue /= 6.0f;
|
||||
}
|
||||
}
|
||||
|
||||
float sl_hue2rgb(float p, float q, float t)
|
||||
{
|
||||
if (t < 0.0f) {
|
||||
t += 1.0f;
|
||||
}
|
||||
if (t > 1.0f) {
|
||||
t -= 1.0f;
|
||||
}
|
||||
if (t < 1.0f / 6.0f) {
|
||||
return p + (q - p) * 6.0f * t;
|
||||
}
|
||||
if (t < 1.0f / 2.0f) {
|
||||
return q;
|
||||
}
|
||||
if (t < 2.0f / 3.0f) {
|
||||
return p + (q - p) * (2.0f / 3.0f - t) * 6.0f;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void sl_hsb2rgb(float hue, float sat, float bri)
|
||||
{
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
|
||||
if (sat == 0.0f) {
|
||||
r = g = b = bri;
|
||||
} else {
|
||||
float q = bri < 0.5f ? bri * (1.0f + sat) : bri + sat - bri * sat;
|
||||
float p = 2.0f * bri - q;
|
||||
r = sl_hue2rgb(p, q, hue + 1.0f / 3.0f);
|
||||
g = sl_hue2rgb(p, q, hue);
|
||||
b = sl_hue2rgb(p, q, hue - 1.0f / 3.0f);
|
||||
}
|
||||
sl_dcolor[0] = (uint8_t)(r * 255 + 0.5f);
|
||||
sl_dcolor[1] = (uint8_t)(g * 255 + 0.5f);
|
||||
sl_dcolor[2] = (uint8_t)(b * 255 + 0.5f);
|
||||
sl_setColor();
|
||||
}
|
||||
sl_setDim(sysCfg.led_dimmer[0]);
|
||||
dcolor.R = sl_dcolor[0];
|
||||
dcolor.G = sl_dcolor[1];
|
||||
dcolor.B = sl_dcolor[2];
|
||||
HsbColor hsb = HsbColor(dcolor);
|
||||
*hue = hsb.H;
|
||||
*sat = hsb.S;
|
||||
*bri = hsb.B;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
|
@ -458,7 +393,8 @@ void sl_replaceHSB(String *response)
|
|||
} else {
|
||||
response->replace("{h}", "0");
|
||||
response->replace("{s}", "0");
|
||||
response->replace("{b}", String((uint8_t)(2.54f * (float)sysCfg.led_dimmer[0])));
|
||||
// response->replace("{b}", String((uint8_t)(2.54f * (float)sysCfg.led_dimmer[0])));
|
||||
response->replace("{b}", String((uint8_t)(0.01f * (float)sysCfg.led_dimmer[0])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,33 +405,68 @@ void sl_getHSB(float *hue, float *sat, float *bri)
|
|||
} else {
|
||||
*hue = 0;
|
||||
*sat = 0;
|
||||
*bri = (2.54f * (float)sysCfg.led_dimmer[0]);
|
||||
// *bri = (2.54f * (float)sysCfg.led_dimmer[0]);
|
||||
*bri = (0.01f * (float)sysCfg.led_dimmer[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void sl_setHSB(float hue, float sat, float bri)
|
||||
void sl_setHSB(float hue, float sat, float bri, float ct)
|
||||
{
|
||||
char svalue[MESSZ];
|
||||
HsbColor hsb;
|
||||
float my_ct;
|
||||
|
||||
/*
|
||||
char log[LOGSZ];
|
||||
char stemp1[10];
|
||||
char stemp2[10];
|
||||
char stemp3[10];
|
||||
char stemp4[10];
|
||||
dtostrf(hue, 1, 3, stemp1);
|
||||
dtostrf(sat, 1, 3, stemp2);
|
||||
dtostrf(bri, 1, 3, stemp3);
|
||||
snprintf_P(log, sizeof(log), PSTR("LED: Hue %s, Sat %s, Bri %s"), stemp1, stemp2, stemp3);
|
||||
dtostrf(ct, 1, 3, stemp4);
|
||||
snprintf_P(log, sizeof(log), PSTR("HUE: Set Hue %s, Sat %s, Bri %s, Ct %s"), stemp1, stemp2, stemp3, stemp4);
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
*/
|
||||
|
||||
if (sfl_flg > 2) {
|
||||
sl_hsb2rgb(hue, sat, bri);
|
||||
hsb.H = hue;
|
||||
hsb.S = sat;
|
||||
hsb.B = bri;
|
||||
RgbColor tmp = RgbColor(hsb);
|
||||
sl_dcolor[0] = tmp.R;
|
||||
sl_dcolor[1] = tmp.G;
|
||||
sl_dcolor[2] = tmp.B;
|
||||
sl_setColor();
|
||||
sl_prepPower(svalue, sizeof(svalue));
|
||||
mqtt_publish_topic_P(5, "COLOR", svalue);
|
||||
} else {
|
||||
uint8_t tmp = (uint8_t)(bri * 100);
|
||||
sysCfg.led_dimmer[0] = tmp;
|
||||
sl_prepPower(svalue, sizeof(svalue));
|
||||
mqtt_publish_topic_P(5, "DIMMER", svalue);
|
||||
if (2 == sfl_flg) {
|
||||
if (ct > 0) {
|
||||
my_ct = ct - 0.306;
|
||||
if (my_ct > 0.694) { // >500 (Warm)
|
||||
my_ct = 0.694;
|
||||
}
|
||||
float fcold = 367 * (0.694 - my_ct); // 0 - 255
|
||||
float fwarm = 367 * my_ct; // 0 - 255
|
||||
float fmax = (fwarm > fcold) ? fwarm : fcold;
|
||||
float fbri = 100 / (fmax / 2.55); // Scale to 255
|
||||
if (bri < 1) {
|
||||
bri = bri + 0.01; // Adjust for sl_setColor
|
||||
}
|
||||
sl_dcolor[0] = (uint8_t)(fcold * fbri * bri); // Cold
|
||||
sl_dcolor[1] = (uint8_t)(fwarm * fbri * bri); // Warm
|
||||
sl_setColor();
|
||||
}
|
||||
sl_prepPower(svalue, sizeof(svalue));
|
||||
mqtt_publish_topic_P(5, "COLOR", svalue);
|
||||
} else {
|
||||
sl_prepPower(svalue, sizeof(svalue));
|
||||
mqtt_publish_topic_P(5, "DIMMER", svalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -533,6 +533,7 @@ void hue_lights(String *path)
|
|||
float bri = 0;
|
||||
float hue = 0;
|
||||
float sat = 0;
|
||||
float ct = 0;
|
||||
bool resp = false;
|
||||
bool on = false;
|
||||
bool change = false;
|
||||
|
@ -636,9 +637,21 @@ void hue_lights(String *path)
|
|||
response.replace("{res}", String(tmp));
|
||||
change = true;
|
||||
}
|
||||
if (hue_json.containsKey("ct")) { // Color temperature 153 (Cold) to 500 (Warm)
|
||||
tmp = hue_json["ct"];
|
||||
ct = (float)tmp / 500.0f;
|
||||
if (resp) {
|
||||
response += ",";
|
||||
}
|
||||
response += FPSTR(HUE_LIGHT_RESPONSE_JSON);
|
||||
response.replace("{id}", String(device));
|
||||
response.replace("{cmd}", "ct");
|
||||
response.replace("{res}", String(tmp));
|
||||
change = true;
|
||||
}
|
||||
if (change) {
|
||||
if (sfl_flg) {
|
||||
sl_setHSB(hue, sat, bri);
|
||||
sl_setHSB(hue, sat, bri, ct);
|
||||
#ifdef USE_WS2812
|
||||
}
|
||||
else if (pin[GPIO_WS2812] < 99) {
|
||||
|
@ -655,6 +668,9 @@ void hue_lights(String *path)
|
|||
else {
|
||||
response = FPSTR(HUE_ERROR_JSON);
|
||||
}
|
||||
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
|
||||
|
||||
webServer->send(200, FPSTR(HDR_CTYPE_JSON), response);
|
||||
}
|
||||
else if(path->indexOf("/lights/") >= 0) { // Got /lights/ID
|
||||
|
@ -678,6 +694,9 @@ void hue_lights(String *path)
|
|||
|
||||
void hue_groups(String *path)
|
||||
{
|
||||
/*
|
||||
* http://sonoff/api/username/groups?1={"name":"Woonkamer","lights":[],"type":"Room","class":"Living room"})
|
||||
*/
|
||||
String response = "{}";
|
||||
|
||||
if (path->endsWith("/0")) {
|
||||
|
@ -721,7 +740,7 @@ void handle_hue_api(String *path)
|
|||
else if (path->endsWith("/")) hue_auth(path); // New HUE App setup
|
||||
else if (path->endsWith("/config")) hue_config(path);
|
||||
else if (path->indexOf("/lights") >= 0) hue_lights(path);
|
||||
else if (path->indexOf("/groups") >= 0) hue_groups(path);
|
||||
else if (path->indexOf("/groups") >= 0) hue_groups(path);
|
||||
else if (path->endsWith("/schedules")) hue_todo(path);
|
||||
else if (path->endsWith("/sensors")) hue_todo(path);
|
||||
else if (path->endsWith("/scenes")) hue_todo(path);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* WS2812 Leds using NeopixelBus library
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include <NeoPixelBus.h>
|
||||
//#include <NeoPixelBus.h> // Global defined as also used by Sonoff Led
|
||||
|
||||
#ifdef USE_WS2812_DMA
|
||||
#if (USE_WS2812_CTYPE == 1)
|
||||
|
@ -145,37 +145,6 @@ void ws2812_setColor(uint16_t led, char* colstr)
|
|||
}
|
||||
}
|
||||
|
||||
void ws2812_replaceHSB(String *response)
|
||||
{
|
||||
ws2812_setDim(sysCfg.ws_dimmer);
|
||||
HsbColor hsb = HsbColor(dcolor);
|
||||
response->replace("{h}", String((uint16_t)(65535.0f * hsb.H)));
|
||||
response->replace("{s}", String((uint8_t)(254.0f * hsb.S)));
|
||||
response->replace("{b}", String((uint8_t)(254.0f * hsb.B)));
|
||||
}
|
||||
|
||||
void ws2812_getHSB(float *hue, float *sat, float *bri)
|
||||
{
|
||||
ws2812_setDim(sysCfg.ws_dimmer);
|
||||
HsbColor hsb = HsbColor(dcolor);
|
||||
*hue = hsb.H;
|
||||
*sat = hsb.S;
|
||||
*bri = hsb.B;
|
||||
}
|
||||
|
||||
void ws2812_setHSB(float hue, float sat, float bri)
|
||||
{
|
||||
char rgb[7];
|
||||
|
||||
HsbColor hsb;
|
||||
hsb.H = hue;
|
||||
hsb.S = sat;
|
||||
hsb.B = bri;
|
||||
RgbColor tmp = RgbColor(hsb);
|
||||
sprintf(rgb,"%02X%02X%02X", tmp.R, tmp.G, tmp.B);
|
||||
ws2812_setColor(0,rgb);
|
||||
}
|
||||
|
||||
void ws2812_getColor(uint16_t led, char* svalue, uint16_t ssvalue)
|
||||
{
|
||||
RgbColor mcolor;
|
||||
|
@ -504,6 +473,41 @@ void ws2812_init(uint8_t powerbit)
|
|||
ws2812_pixels();
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Hue support
|
||||
\*********************************************************************************************/
|
||||
|
||||
void ws2812_replaceHSB(String *response)
|
||||
{
|
||||
ws2812_setDim(sysCfg.ws_dimmer);
|
||||
HsbColor hsb = HsbColor(dcolor);
|
||||
response->replace("{h}", String((uint16_t)(65535.0f * hsb.H)));
|
||||
response->replace("{s}", String((uint8_t)(254.0f * hsb.S)));
|
||||
response->replace("{b}", String((uint8_t)(254.0f * hsb.B)));
|
||||
}
|
||||
|
||||
void ws2812_getHSB(float *hue, float *sat, float *bri)
|
||||
{
|
||||
ws2812_setDim(sysCfg.ws_dimmer);
|
||||
HsbColor hsb = HsbColor(dcolor);
|
||||
*hue = hsb.H;
|
||||
*sat = hsb.S;
|
||||
*bri = hsb.B;
|
||||
}
|
||||
|
||||
void ws2812_setHSB(float hue, float sat, float bri)
|
||||
{
|
||||
char rgb[7];
|
||||
|
||||
HsbColor hsb;
|
||||
hsb.H = hue;
|
||||
hsb.S = sat;
|
||||
hsb.B = bri;
|
||||
RgbColor tmp = RgbColor(hsb);
|
||||
sprintf(rgb,"%02X%02X%02X", tmp.R, tmp.G, tmp.B);
|
||||
ws2812_setColor(0,rgb);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Commands
|
||||
\*********************************************************************************************/
|
||||
|
|
Loading…
Reference in New Issue