/** * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. */ // Enable debug prints to serial monitor #define MY_DEBUG // configure radio #define MY_RADIO_RFM69 /** @brief RFM69 frequency to use (RF69_433MHZ for 433MHz, RF69_868MHZ for 868MHz or RF69_915MHZ for 915MHz). */ #define MY_RFM69_FREQUENCY RF69_868MHZ /** @brief Enable this if you're running the RFM69HW model. */ //#define MY_IS_RFM69HW /** @brief RFM69 Network ID. Use the same for all nodes that will talk to each other. */ #define MY_RFM69_NETWORKID 1 /** @brief Node id defaults to AUTO (tries to fetch id from controller). */ #define MY_NODE_ID 3 /** @brief If set, transport traffic is unmonitored and GW connection is optional */ #define MY_TRANSPORT_DONT_CARE_MODE /** @brief Node parent defaults to AUTO (tries to find a parent automatically). */ #define MY_PARENT_NODE_ID 0 /** @brief The user-defined AES key to use for EEPROM personalization */ #include "aes_key.h" // Enable repeater functionality for this node //#define MY_REPEATER_FEATURE /** @brief Enables RFM69 automatic transmit power control class. */ //#define MY_RFM69_ATC #ifdef MY_AES_KEY /** @brief enables RFM69 encryption */ #define MY_RFM69_ENABLE_ENCRYPTION #endif #include #include #include #define RELAY_1_PIN 4 // pin number of first relay (second on pin+1 etc) #define NUMBER_OF_RELAYS 1 // Total number of attached relays #define RELAY_ON 1 // GPIO value to write to turn on attached relay #define RELAY_OFF 0 // GPIO value to write to turn off attached relay #define RGB_PIN 7 #define NUM_LEDS 30 #define RGB_CHIPSET WS2812B #define RGB_COLOR_ORDER GRB #define RGB_CHILD_ID 0 #define TEMP_READ_INTERVAL 1000L // read temp every 1 sec #define TEMP_N_READS_MSG 60*60 // force temp message every n reads #define TEMP_OFFSET 0 #define TEMP_CHILD_ID 254 MyMessage msgRGB(RGB_CHILD_ID, 0); static uint8_t brightness = 128; MyMessage msgRelais(0, V_STATUS); unsigned long lastTempUpdate = millis(); unsigned int numTempUpdates = 0; float lastTemp = 0; MyMessage msgTemp(TEMP_CHILD_ID, V_TEMP); CRGB leds[NUM_LEDS]; void changeRelay(uint8_t relay, uint8_t val, bool send_update=false); void before() { // set relay pins to output mode + restore to last known state for (uint8_t relay = 0; relay < NUMBER_OF_RELAYS; relay++) { pinMode(relay + RELAY_1_PIN, OUTPUT); digitalWrite(relay + RELAY_1_PIN, loadState(relay) ? RELAY_ON : RELAY_OFF); } #ifdef MY_AES_KEY const uint8_t user_aes_key[16] = { MY_AES_KEY }; uint8_t cur_aes_key[16]; hwReadConfigBlock((void*)&cur_aes_key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, sizeof(cur_aes_key)); if (memcmp(&user_aes_key, &cur_aes_key, 16) != 0) { hwWriteConfigBlock((void*)user_aes_key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, sizeof(user_aes_key)); debug(PSTR("AES key written\n")); } #endif } void setup() { #ifdef MY_RFM69_ATC _radio.enableAutoPower(-70); debug(PSTR("ATC enabled\n")); #endif FastLED.addLeds(leds, NUM_LEDS); //TODO restore mode(static/ambilight)/color/brightness from flash? FastLED.setBrightness(brightness); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Ambilight", "1.0"); // Register all sensors to gw (they will be created as child devices) present(0, S_RGB_LIGHT, "ambilight"); #if 0 for (uint8_t relay = 0; relay < NUMBER_OF_RELAYS; relay++) present(relay + 1, S_BINARY); present(TEMP_CHILD_ID, S_TEMP); #endif delay(3000); send(msgRGB.setType(V_STATUS).set(1)); delay(500); send(msgRGB.setType(V_DIMMER).set(FastLED.getBrightness())); delay(500); send(msgRGB.setType(V_RGB).set("ffffff")); FastLED.show(); } void loop() { //TODO maybe call _radio.rcCalibration() all 1000x changes? //FastLED.show(); //FastLED.delay(8); #if 0 // check temperature unsigned long now = millis(); if (now - lastTempUpdate > TEMP_READ_INTERVAL) { float temp = _radio.readTemperature() + TEMP_OFFSET; lastTempUpdate = now; if (isnan(temp)) Serial.println("Failed reading temperature"); else if (abs(temp - lastTemp) >= 2 || numTempUpdates == TEMP_N_READS_MSG) { lastTemp = temp; numTempUpdates = 0; send(msgTemp.set(temp, 2)); #ifdef MY_DEBUG char str_temp[6]; dtostrf(temp, 4, 2, str_temp); debug(PSTR("Temperature: %s °C\n"), str_temp); #endif } else ++numTempUpdates; } #endif } void receive(const MyMessage &message) { Serial.println(_radio.readRSSI()); if (message.sensor == RGB_CHILD_ID) { if (mGetCommand(message) == C_SET) { if (message.type == V_STATUS) { bool val = message.getBool(); // datatype=0, message=0/1 Serial.println("light on/off"); //TODO restore brightness. } else if (message.type == V_RGB && mGetLength(message) == 6) { uint32_t colorcode = strtol(message.getString(), NULL, 16); fill_solid(leds, NUM_LEDS, CRGB(colorcode)); FastLED.show(); } else if (message.type == V_PERCENTAGE) { //TODO fade? uint8_t val = message.getByte(); if (val < 0 || val > 100) return; Serial.print("dim: "); Serial.println(val, DEC); brightness = map(val, 0, 100, 0, 255); Serial.println(brightness, DEC); // datatype=0, message=1-100 FastLED.setBrightness(brightness); FastLED.show(); } } } #if 0 if (message.type == V_STATUS && message.sensor >= 1) { uint8_t relay = message.sensor - 1; if (relay >= NUMBER_OF_RELAYS) { Serial.print("Invalid relay index:"); Serial.println(relay); return; } if (mGetCommand(message) == C_REQ) send(msg.setSensor(relay + 1).set(digitalRead(relay + RELAY_1_PIN))); else if (mGetCommand(message) == C_SET) changeRelay(relay, message.getBool() ? RELAY_ON : RELAY_OFF); } #endif } void changeRelay(uint8_t relay, uint8_t value, bool send_update) { if (relay >= NUMBER_OF_RELAYS) return; Serial.print("Incoming change for relay: "); Serial.print(relay); Serial.print(", New status: "); Serial.println(value); // change relay state + store state in eeprom digitalWrite(relay + RELAY_1_PIN, value); saveState(relay, value); // send msg if (send_update) send(msgRelais.setSensor(relay + 1).set(value)); }