Compare commits

...

3 Commits

10 changed files with 75 additions and 62 deletions

View File

@ -1,14 +1,17 @@
#pragma once #pragma once
class Corner;
#include "my_fastled.h" #include "my_fastled.h"
#include <vector> #include <vector>
#include <list> #include <list>
#include "edge.h" #include "node.h"
class Corner { class Corner {
public: public:
Edge* e1; Node* node;
Edge* e2; uint8_t number;
Corner(Edge* e1, Edge* e2); Corner(Node* node, uint8_t number);
std::list<uint16_t> _leds; std::list<uint16_t> _leds;
std::vector<Corner*> _long_neighbours {}; std::vector<Corner*> _long_neighbours {};
std::vector<Corner*> _short_neighbours {}; std::vector<Corner*> _short_neighbours {};

View File

@ -1,6 +0,0 @@
#pragma once
class Edge {
public:
Edge* neighbour = nullptr;
};

View File

@ -1,7 +1,9 @@
#pragma once #pragma once
class Node;
#include <Arduino.h> #include <Arduino.h>
#include "config.h" #include "config.h"
#include "edge.h"
#include "corner.h" #include "corner.h"
#include "prototypes.h" #include "prototypes.h"
@ -20,7 +22,6 @@ class Node {
Coords coords; Coords coords;
uint8_t direction; uint8_t direction;
Node* neighbours[CORNERS_PER_PART]; Node* neighbours[CORNERS_PER_PART];
Edge* edges[CORNERS_PER_PART];
Corner* _corners[CORNERS_PER_PART]; Corner* _corners[CORNERS_PER_PART];
Node(uint16_t number, Coords c, uint8_t direction); Node(uint16_t number, Coords c, uint8_t direction);
Node* create_neighbour(uint8_t edge); Node* create_neighbour(uint8_t edge);

View File

@ -2,15 +2,14 @@
#include "my_fastled.h" #include "my_fastled.h"
#include <list> #include <list>
#include <vector> #include <vector>
#include <map>
#include "config.h" #include "config.h"
#include "node.h" #include "node.h"
#include "edge.h"
#include "corner.h" #include "corner.h"
class Node; class Node;
extern std::vector<Node*> nodes; extern std::vector<Node*> nodes;
extern std::list<Edge*> edges;
extern std::vector<Corner*> corners; extern std::vector<Corner*> corners;
extern CRGB leds[LED_COUNT]; extern CRGB leds[LED_COUNT];
@ -28,6 +27,8 @@ enum AnimationMode {
AM_STATIC AM_STATIC
}; };
extern std::map<AnimationMode, const char*> animation_mode_names;
extern AnimationMode mode; extern AnimationMode mode;
extern AnimationMode temp_mode; extern AnimationMode temp_mode;
extern unsigned long temp_mode_until; extern unsigned long temp_mode_until;

View File

@ -15,6 +15,7 @@ class State {
void set(String key, String value); void set(String key, String value);
void commit(); void commit();
static void publish_current_state(); static void publish_current_state();
static AnimationMode get_active_mode();
void parse_state(String state); void parse_state(String state);
void parse_mode(String mode); void parse_mode(String mode);

View File

@ -2,7 +2,7 @@
#include "prototypes.h" #include "prototypes.h"
#include "tools.h" #include "tools.h"
Corner::Corner(Edge* new_e1, Edge* new_e2): e1(new_e1), e2(new_e2) { Corner::Corner(Node* no, uint8_t nu): node(no), number(nu) {
} }

View File

@ -5,7 +5,6 @@
#include "config.h" #include "config.h"
#include "tools.h" #include "tools.h"
#include "node.h" #include "node.h"
#include "edge.h"
#include "corner.h" #include "corner.h"
#include "prototypes.h" #include "prototypes.h"
#include "mqtt.h" #include "mqtt.h"
@ -13,7 +12,6 @@
#include "syslog.h" #include "syslog.h"
std::vector<Node*> nodes; std::vector<Node*> nodes;
std::list<Edge*> edges;
std::vector<Corner*> corners; std::vector<Corner*> corners;
CRGB leds[LED_COUNT]; CRGB leds[LED_COUNT];
@ -44,24 +42,12 @@ void setup_layout() {
nodes.push_back(current_node); nodes.push_back(current_node);
} }
for(Node* node: nodes) { bool verbose = false;
for(Edge* edge: node->edges) {
auto e = std::find(edges.begin(), edges.end(), edge);
if (e == edges.end()) {
edges.push_back(edge);
}
}
LOGln("Node %p:", node);
for(Node* n : node->neighbours) {
LOGln(" %p", n);
}
}
for (Node* n1 : nodes) { for (Node* n1 : nodes) {
LOGln("Looking for neighbours of node #%d @ %d,%d", n1->_number, n1->coords.x, n1->coords.y); if (verbose) LOGln("Looking for neighbours of node #%d @ %d,%d", n1->_number, n1->coords.x, n1->coords.y);
for(int edge=0; edge<CORNERS_PER_PART; edge++) { for(int edge=0; edge<CORNERS_PER_PART; edge++) {
Coords c = n1->coords_at_direction(edge); Coords c = n1->coords_at_direction(edge);
LOGln(" Chcking edge %d @ %d,%d...", edge, c.x, c.y); if (verbose) LOGln(" Chcking edge %d @ %d,%d...", edge, c.x, c.y);
Node* found = nullptr; Node* found = nullptr;
for(Node* n2 : nodes) { for(Node* n2 : nodes) {
@ -74,7 +60,7 @@ void setup_layout() {
} }
} }
if (found != nullptr) { if (found != nullptr) {
LOGln(" Found node #%d", found->_number); if (verbose) LOGln(" Found node #%d", found->_number);
uint8_t inverse_dir = (n1->direction + 2*edge + 3) % 6; uint8_t inverse_dir = (n1->direction + 2*edge + 3) % 6;
int8_t e = (inverse_dir - found->direction) % 6; int8_t e = (inverse_dir - found->direction) % 6;
if (e < 0) e+=6; if (e < 0) e+=6;
@ -85,30 +71,39 @@ void setup_layout() {
int8_t e2 = (e - 1) % CORNERS_PER_PART; int8_t e2 = (e - 1) % CORNERS_PER_PART;
if (e2<0) e2+=CORNERS_PER_PART; if (e2<0) e2+=CORNERS_PER_PART;
LOGln(" Mapping Corner #%d,%d with #%d,%d", n1->_number, edge, found->_number, e2); if (verbose) LOGln(" Mapping Corner #%d,%d with #%d,%d", n1->_number, edge, found->_number, e2);
n1->_corners[edge]->_short_neighbours.push_back(found->_corners[e2]); n1->_corners[edge]->_short_neighbours.push_back(found->_corners[e2]);
LOGln(" Mapping Corner #%d,%d with #%d,%d", n1->_number, e1, found->_number, e); if (verbose) LOGln(" Mapping Corner #%d,%d with #%d,%d", n1->_number, e1, found->_number, e);
n1->_corners[e1]->_short_neighbours.push_back(found->_corners[e]); n1->_corners[e1]->_short_neighbours.push_back(found->_corners[e]);
} else { } else {
LOGln(" No match."); if (verbose) LOGln(" No match.");
} }
} }
} }
for(Corner* corner: corners) { for (Node* node : nodes) {
LOGln("Corner %p:", corner); LOGln("Node #%d:", node->_number);
for(Corner* corner : node->_corners) {
LOGln(" Corner #%d,%d:", node->_number, corner->number);
for (auto c: corner->_long_neighbours) { for (auto c: corner->_long_neighbours) {
LOGln(" Long: %p", c); LOGln(" Long neighbour: #%d,%d", c->node->_number, c->number);
} }
for (auto c: corner->_short_neighbours) { for (auto c: corner->_short_neighbours) {
LOGln(" Short: %p", c); LOGln(" Short neighbour: #%d,%d", c->node->_number, c->number);
}
}
for (int i=0; i<CORNERS_PER_PART; i++) {
if (node->neighbours[i]==nullptr) {
LOGln(" Neighbour %d: NULL", i);
} else {
LOGln(" Neighbour %d: #%d", i, node->neighbours[i]->_number);
}
} }
} }
LOGln("Counts:"); LOGln("Counts:");
LOGln("Nodes: %3d", nodes.size()); LOGln("Nodes: %3d", nodes.size());
LOGln("Edges: %3d", edges.size());
LOGln("Corners: %3d", corners.size()); LOGln("Corners: %3d", corners.size());
} }
@ -213,6 +208,8 @@ void setup() {
for(Corner* corner : corners) { for(Corner* corner : corners) {
corner->set_color(CRGB::Black); corner->set_color(CRGB::Black);
} }
State::publish_current_state();
} }
void loop() { void loop() {
@ -236,19 +233,7 @@ void loop() {
if (speedup > 0 && (millis() - last_loop > (20 / speedup) || last_loop > millis())) { if (speedup > 0 && (millis() - last_loop > (20 / speedup) || last_loop > millis())) {
looping = false; looping = false;
AnimationMode active_mode = mode; AnimationMode active_mode = State::get_active_mode();
if (temp_mode_until > 0) {
if (temp_mode_until>millis()) {
active_mode = temp_mode;
} else {
temp_mode_until = 0;
if (return_to_brightness != -1) {
FastLED.setBrightness(return_to_brightness);
return_to_brightness = -1;
}
State::publish_current_state();
}
}
if (active_mode == AM_CORNERS || active_mode == AM_FIRST_CORNER) { if (active_mode == AM_CORNERS || active_mode == AM_FIRST_CORNER) {
for(Corner* corner: corners) { for(Corner* corner: corners) {

View File

@ -9,12 +9,12 @@ Node::Node(uint16_t number, Coords c, uint8_t _dir) {
LOGln("Created Node #%d at coordinates %d,%d with direction %d.", _number, coords.x, coords.y, direction); LOGln("Created Node #%d at coordinates %d,%d with direction %d.", _number, coords.x, coords.y, direction);
for(int i=0; i<CORNERS_PER_PART; i++) { for(int i=0; i<CORNERS_PER_PART; i++) {
edges[i] = new Edge(); neighbours[i] = nullptr;
} }
Corner* last_corner = nullptr; Corner* last_corner = nullptr;
for(int i=0; i<CORNERS_PER_PART; i++) { for(int i=0; i<CORNERS_PER_PART; i++) {
Corner* c = new Corner(edges[i], edges[(i+1) % CORNERS_PER_PART]); Corner* c = new Corner(this, i);
for(int j=0; j<LEDS_PER_CORNER; j++) { for(int j=0; j<LEDS_PER_CORNER; j++) {
c->add_led(number * CORNERS_PER_PART * LEDS_PER_CORNER + i * LEDS_PER_CORNER + j); c->add_led(number * CORNERS_PER_PART * LEDS_PER_CORNER + i * LEDS_PER_CORNER + j);
} }
@ -42,9 +42,6 @@ Node* Node::create_neighbour(uint8_t edge) {
node->neighbours[0] = this; node->neighbours[0] = this;
neighbours[edge] = node; neighbours[edge] = node;
node->edges[0]->neighbour = this->edges[edge];
this->edges[edge]->neighbour = node->edges[0];
return node; return node;
} }

13
src/prototypes.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "prototypes.h"
std::map<AnimationMode, const char*> animation_mode_names {
{AM_CORNERS, "corners"},
{AM_FLASH, "flash"},
{AM_FIRST_CORNER, "first_corner"},
{AM_NODES, "nodes"},
{AM_FIRST_NODE, "first_node"},
{AM_OFF, "off"},
{AM_ERROR, "error"},
{AM_NONE, "NONE"},
{AM_STATIC, "static"}
};

View File

@ -106,12 +106,30 @@ void State::publish_current_state() {
StaticJsonDocument<512> json; StaticJsonDocument<512> json;
json["state"] = (mode==AM_OFF) ? "OFF" : "ON"; json["state"] = (mode==AM_OFF) ? "OFF" : "ON";
json["brightness"] = FastLED.getBrightness(); json["brightness"] = FastLED.getBrightness();
json["effect"] = mode; json["effect"] = animation_mode_names[get_active_mode()];
JsonObject rgb = json.createNestedObject("rgb"); JsonObject rgb = json.createNestedObject("rgb");
rgb["r"] = color.r; rgb["r"] = color.r;
rgb["g"] = color.g; rgb["g"] = color.g;
rgb["b"] = color.b; rgb["b"] = color.b;
String result = ""; String result = "";
serializeJson(json, result); serializeJson(json, result);
LOGln("Reporting current state: %s", result.c_str());
mqtt_publish_current_state(result); mqtt_publish_current_state(result);
} }
AnimationMode State::get_active_mode() {
AnimationMode active_mode = mode;
if (temp_mode_until > 0) {
if (temp_mode_until>millis()) {
active_mode = temp_mode;
} else {
temp_mode_until = 0;
if (return_to_brightness != -1) {
FastLED.setBrightness(return_to_brightness);
return_to_brightness = -1;
}
State::publish_current_state();
}
}
return active_mode;
}