diff --git a/include/node.h b/include/node.h index bc0e1fd..5d299bc 100644 --- a/include/node.h +++ b/include/node.h @@ -26,6 +26,7 @@ class Node { Node(uint16_t number, Coords c, uint8_t direction); Node* create_neighbour(uint8_t edge); Coords coords_at_direction(uint8_t edge); + uint16_t distance_from_start = 0; void blend_to(CRGB color, uint16_t effect_id=0, uint8_t effect_speed=0); void set_color(CRGB color); diff --git a/include/prototypes.h b/include/prototypes.h index 4ce4c85..c764f8b 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -24,7 +24,8 @@ enum AnimationMode { AM_OFF, AM_ERROR, AM_NONE, - AM_STATIC + AM_STATIC, + AM_RAINBOW }; extern std::map animation_mode_names; diff --git a/src/main.cpp b/src/main.cpp index 2e85faf..2b733d4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,6 +35,7 @@ void setup_layout() { LOGln("Setting up layout..."); uint8_t layout[] = LAYOUT; Node* current_node = new Node(0, {0, 0}, 0); + current_node->distance_from_start = 1; nodes.push_back(current_node); for(uint16_t i=0; i_number, n1->coords.x, n1->coords.y); for(int edge=0; edgecoords_at_direction(edge); - if (verbose) LOGln(" Chcking edge %d @ %d,%d...", edge, c.x, c.y); + if (verbose) LOGln(" Checking edge %d @ %d,%d...", edge, c.x, c.y); Node* found = nullptr; for(Node* n2 : nodes) { @@ -82,8 +83,25 @@ void setup_layout() { } } + bool checked_all = false; + while (!checked_all) { + checked_all = true; + for(Node* n : nodes) { + if (n->distance_from_start == 0) { + checked_all = false; + } else { + for(int i=0; ineighbours[i] != nullptr && (n->neighbours[i]->distance_from_start==0 || n->neighbours[i]->distance_from_start > n->distance_from_start)) { + n->neighbours[i]->distance_from_start = n->distance_from_start+1; + } + } + } + } + } + for (Node* node : nodes) { LOGln("Node #%d:", node->_number); + LOGln(" Distance from start: %d", node->distance_from_start); for(Corner* corner : node->_corners) { LOGln(" Corner #%d,%d:", node->_number, corner->number); for (auto c: corner->_long_neighbours) { @@ -95,7 +113,7 @@ void setup_layout() { } for (int i=0; ineighbours[i]==nullptr) { - LOGln(" Neighbour %d: NULL", i); + LOGln(" Neighbour %d: -", i); } else { LOGln(" Neighbour %d: #%d", i, node->neighbours[i]->_number); } @@ -276,6 +294,13 @@ void loop() { for(Node* node : nodes) { node->set_color(active_mode == AM_OFF ? CRGB::Black : color); } + } else if (active_mode == AM_RAINBOW) { + const uint8_t speed = 5; // seconds (approx.) for full color sweep + const uint8_t diff_per_node = 5; + uint8_t base_hue = (millis() * 256 / speed) / 1000; + for(Node* node : nodes) { + node->set_color(CHSV(base_hue + diff_per_node * node->distance_from_start, 255, 255)); + } } else { // This includes AM_ERROR for(Node* node : nodes) { node->set_color(CRGB::Black); diff --git a/src/mqtt.cpp b/src/mqtt.cpp index a2969d8..608fd9f 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -11,7 +11,7 @@ LOGln("Connecting to MQTT broker..."); char buffer[40]; snprintf(buffer, 40, "online %s", wifi.localIP().toString().c_str()); mqtt.publish(MQTT_TOPIC "available_long", buffer, true); - mqtt.subscribe(MQTT_TOPIC"cmnd"); + mqtt.subscribe(MQTT_TOPIC "cmnd"); String discovery_msg = "{" "\"~\":\"" MQTT_TOPIC "\",\"avty_t\":\"~available\",\"cmd_t\":\"~cmnd\",\"stat_t\":\"~state\"," "\"name\":\"ESPleaf\",\"schema\":\"json\"," @@ -68,6 +68,7 @@ void mqtt_setup() { void mqtt_loop() { if (!mqtt.connected()) { + LOGln("MQTT disconnected. Reason: %d", mqtt.state()); connect(); } mqtt.loop(); diff --git a/src/prototypes.cpp b/src/prototypes.cpp index 051ab60..26ce920 100644 --- a/src/prototypes.cpp +++ b/src/prototypes.cpp @@ -9,5 +9,6 @@ std::map animation_mode_names { {AM_OFF, "off"}, {AM_ERROR, "error"}, {AM_NONE, "NONE"}, - {AM_STATIC, "static"} + {AM_STATIC, "static"}, + {AM_RAINBOW, "rainbow"} }; diff --git a/src/state.cpp b/src/state.cpp index 8b95203..7fe6c88 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -27,14 +27,18 @@ void State::parse_state(String state) { } void State::parse_mode(String mode) { - if (mode.equals("nodes")) { set_mode(AM_NODES); } - else if (mode.equals("first_node")) { set_mode(AM_FIRST_NODE); } - else if (mode.equals("corners")) { set_mode(AM_CORNERS); } - else if (mode.equals("first_corner")) { set_mode(AM_FIRST_CORNER); } - else if (mode.equals("off")) { set_mode(AM_OFF); } - else if (mode.equals("flash")) { set_mode(AM_FLASH); } - else if (mode.equals("static")) { set_mode(AM_STATIC); } - else { LOGln("parse_mode: Unknown mode '%s'.", mode.c_str()); } + AnimationMode m = AM_NONE; + for (std::pair pair : animation_mode_names) { + if (mode.equals(pair.second)) { + m = pair.first; + break; + } + } + if (m == AM_NONE) { + LOGln("parse_mode: Unknown mode '%s'.", mode.c_str()); + } else { + set_mode(m); + } } void State::set_mode(AnimationMode m) {