@ -18,13 +18,101 @@ typedef struct {
unsigned char led ;
} relay_t ;
std : : vector < relay_t > _relays ;
Ticker pulseTicker ;
bool recursive = false ;
# ifdef SONOFF_DUAL
unsigned char dualRelayS tatus = 0 ;
# if RELAY_PROVIDER == RELAY_PROVIDER _DUAL
unsigned char _dual_s tatus = 0 ;
# endif
Ticker pulseTicker ;
bool recursive = false ;
# if RELAY_PROVIDER == RELAY_PROVIDER_MY9291
# include <my9291.h>
my9291 _my9291 = my9291 ( MY9291_DI_PIN , MY9291_DCKI_PIN , MY9291_COMMAND ) ;
Ticker colorTicker ;
# endif
// -----------------------------------------------------------------------------
// PROVIDER
// -----------------------------------------------------------------------------
# if RELAY_PROVIDER == RELAY_PROVIDER_MY9291
void setLightColor ( unsigned char red , unsigned char green , unsigned char blue , unsigned char white ) {
// Set new color (if light is open it will automatically change)
_my9291 . setColor ( ( my9291_color_t ) { red , green , blue , white } ) ;
// Delay saving to EEPROM 5 seconds to avoid wearing it out unnecessarily
colorTicker . once ( 5 , saveLightColor ) ;
}
String getLightColor ( ) {
char buffer [ 16 ] ;
my9291_color_t color = _my9291 . getColor ( ) ;
sprintf ( buffer , " %d,%d,%d,%d " , color . red , color . green , color . blue , color . white ) ;
return String ( buffer ) ;
}
void saveLightColor ( ) {
my9291_color_t color = _my9291 . getColor ( ) ;
setSetting ( " colorRed " , color . red ) ;
setSetting ( " colorGreen " , color . green ) ;
setSetting ( " colorBlue " , color . blue ) ;
setSetting ( " colorWhite " , color . white ) ;
saveSettings ( ) ;
}
void retrieveLightColor ( ) {
unsigned int red = getSetting ( " colorRed " , MY9291_COLOR_RED ) . toInt ( ) ;
unsigned int green = getSetting ( " colorGreen " , MY9291_COLOR_GREEN ) . toInt ( ) ;
unsigned int blue = getSetting ( " colorBlue " , MY9291_COLOR_BLUE ) . toInt ( ) ;
unsigned int white = getSetting ( " colorWhite " , MY9291_COLOR_WHITE ) . toInt ( ) ;
_my9291 . setColor ( ( my9291_color_t ) { red , green , blue , white } ) ;
}
# endif
void relayProviderStatus ( unsigned char id , bool status ) {
# if RELAY_PROVIDER == RELAY_PROVIDER_DUAL
_dual_status ^ = ( 1 < < id ) ;
Serial . flush ( ) ;
Serial . write ( 0xA0 ) ;
Serial . write ( 0x04 ) ;
Serial . write ( _dual_status ) ;
Serial . write ( 0xA1 ) ;
Serial . flush ( ) ;
# endif
# if RELAY_PROVIDER == RELAY_PROVIDER_MY9291
_my9291 . setState ( status ) ;
# endif
# if RELAY_PROVIDER == RELAY_PROVIDER_RELAY
digitalWrite ( _relays [ id ] . pin , _relays [ id ] . reverse ? ! status : status ) ;
# endif
}
bool relayProviderStatus ( unsigned char id ) {
# if RELAY_PROVIDER == RELAY_PROVIDER_DUAL
if ( id > = 2 ) return false ;
return ( ( _dual_status & ( 1 < < id ) ) > 0 ) ;
# endif
# if RELAY_PROVIDER == RELAY_PROVIDER_MY9291
return _my9291 . getState ( ) ;
# endif
# if RELAY_PROVIDER == RELAY_PROVIDER_RELAY
if ( id > = _relays . size ( ) ) return false ;
bool status = ( digitalRead ( _relays [ id ] . pin ) = = HIGH ) ;
return _relays [ id ] . reverse ? ! status : status ;
# endif
}
// -----------------------------------------------------------------------------
// RELAY
@ -43,14 +131,7 @@ String relayString() {
}
bool relayStatus ( unsigned char id ) {
# ifdef SONOFF_DUAL
if ( id > = 2 ) return false ;
return ( ( dualRelayStatus & ( 1 < < id ) ) > 0 ) ;
# else
if ( id > = _relays . size ( ) ) return false ;
bool status = ( digitalRead ( _relays [ id ] . pin ) = = HIGH ) ;
return _relays [ id ] . reverse ? ! status : status ;
# endif
return relayProviderStatus ( id ) ;
}
void relayPulse ( unsigned char id ) {
@ -120,19 +201,7 @@ bool relayStatus(unsigned char id, bool status, bool report) {
DEBUG_MSG ( " [RELAY] %d => %s \n " , id , status ? " ON " : " OFF " ) ;
changed = true ;
# ifdef SONOFF_DUAL
dualRelayStatus ^ = ( 1 < < id ) ;
Serial . flush ( ) ;
Serial . write ( 0xA0 ) ;
Serial . write ( 0x04 ) ;
Serial . write ( dualRelayStatus ) ;
Serial . write ( 0xA1 ) ;
Serial . flush ( ) ;
# else
digitalWrite ( _relays [ id ] . pin , _relays [ id ] . reverse ? ! status : status ) ;
# endif
relayProviderStatus ( id , status ) ;
if ( _relays [ id ] . led > 0 ) {
ledStatus ( _relays [ id ] . led - 1 , status ) ;
@ -370,42 +439,78 @@ void relayMQTTCallback(unsigned int type, const char * topic, const char * paylo
if ( type = = MQTT_CONNECT_EVENT ) {
relayMQTT ( ) ;
char buffer [ strlen ( MQTT_RELAY_TOPIC ) + mqttSetter . length ( ) + 10 ] ;
char buffer [ strlen ( MQTT_RELAY_TOPIC ) + mqttSetter . length ( ) + 20 ] ;
sprintf ( buffer , " %s/+%s " , MQTT_RELAY_TOPIC , mqttSetter . c_str ( ) ) ;
mqttSubscribe ( buffer ) ;
# if RELAY_PROVIDER == RELAY_PROVIDER_MY9291
sprintf ( buffer , " %s%s " , MQTT_COLOR_TOPIC , mqttSetter . c_str ( ) ) ;
mqttSubscribe ( buffer ) ;
# endif
}
if ( type = = MQTT_MESSAGE_EVENT ) {
// Match topic
char * t = mqttSubtopic ( ( char * ) topic ) ;
if ( strncmp ( t , MQTT_RELAY_TOPIC , strlen ( MQTT_RELAY_TOPIC ) ) ! = 0 ) return ;
int len = mqttSetter . length ( ) ;
if ( strncmp ( t + strlen ( t ) - len , mqttSetter . c_str ( ) , len ) ! = 0 ) return ;
// Get value
unsigned int value = ( char ) payload [ 0 ] - ' 0 ' ;
// Color topic
# if RELAY_PROVIDER == RELAY_PROVIDER_MY9291
if ( strncmp ( t , MQTT_COLOR_TOPIC , strlen ( MQTT_COLOR_TOPIC ) ) = = 0 ) {
// Pulse topic
if ( strncmp ( t + strlen ( MQTT_RELAY_TOPIC ) + 1 , " pulse " , 5 ) = = 0 ) {
relayPulseMode ( value , ! sameSetGet ) ;
return ;
}
unsigned char red , green , blue = 0 ;
// Get relay ID
unsigned int relayID = topic [ strlen ( topic ) - mqttSetter . length ( ) - 1 ] - ' 0 ' ;
if ( relayID > = relayCount ( ) ) {
DEBUG_MSG ( " [RELAY] Wrong relayID (%d) \n " , relayID ) ;
return ;
}
char * p ;
p = strtok ( ( char * ) payload , " , " ) ;
red = atoi ( p ) ;
p = strtok ( NULL , " , " ) ;
if ( p ! = NULL ) {
green = atoi ( p ) ;
p = strtok ( NULL , " , " ) ;
if ( p ! = NULL ) blue = atoi ( p ) ;
} else {
green = blue = red ;
}
if ( ( red = = green ) & & ( green = = blue ) ) {
setLightColor ( 0 , 0 , 0 , red ) ;
} else {
setLightColor ( red , green , blue , 0 ) ;
}
return ;
}
# endif
// Relay topic
if ( strncmp ( t , MQTT_RELAY_TOPIC , strlen ( MQTT_RELAY_TOPIC ) ) = = 0 ) {
// Get value
unsigned int value = ( char ) payload [ 0 ] - ' 0 ' ;
// Pulse topic
if ( strncmp ( t + strlen ( MQTT_RELAY_TOPIC ) + 1 , " pulse " , 5 ) = = 0 ) {
relayPulseMode ( value , ! sameSetGet ) ;
return ;
}
// Get relay ID
unsigned int relayID = topic [ strlen ( topic ) - mqttSetter . length ( ) - 1 ] - ' 0 ' ;
if ( relayID > = relayCount ( ) ) {
DEBUG_MSG ( " [RELAY] Wrong relayID (%d) \n " , relayID ) ;
return ;
}
// Action to perform
if ( value = = 2 ) {
relayToggle ( relayID ) ;
} else {
relayStatus ( relayID , value > 0 , ! sameSetGet ) ;
}
// Action to perform
if ( value = = 2 ) {
relayToggle ( relayID ) ;
} else {
relayStatus ( relayID , value > 0 , ! sameSetGet ) ;
}
}
@ -428,6 +533,11 @@ void relaySetup() {
_relays . push_back ( ( relay_t ) { 0 , 0 } ) ;
_relays . push_back ( ( relay_t ) { 0 , 0 } ) ;
# elif AI_LIGHT
// One dummy relay for the AI Thinker Light
_relays . push_back ( ( relay_t ) { 0 , 0 } ) ;
# else
# ifdef RELAY1_PIN
@ -448,6 +558,10 @@ void relaySetup() {
EEPROM . begin ( 4096 ) ;
byte relayMode = getSetting ( " relayMode " , RELAY_MODE ) . toInt ( ) ;
# if RELAY_PROVIDER == RELAY_PROVIDER_MY9291
retrieveLightColor ( ) ;
# endif
for ( unsigned int i = 0 ; i < _relays . size ( ) ; i + + ) {
pinMode ( _relays [ i ] . pin , OUTPUT ) ;
if ( relayMode = = RELAY_MODE_OFF ) relayStatus ( i , false ) ;