Compare commits
16 Commits
0863380648
...
master
Author | SHA1 | Date | |
---|---|---|---|
d76e088c37 | |||
c9825c8f9b | |||
ae997ef802 | |||
a6af2829ee | |||
0a4a62d7c8 | |||
7747e38253 | |||
b9cfc6568b | |||
1d66f9c541 | |||
f9e6a5ebd6 | |||
a96f6c79e3 | |||
ecf5998510 | |||
0ac4f9b181 | |||
fd44b217a7 | |||
209140cfb7 | |||
bcb5fdc9be | |||
b5bb0feccf |
BIN
data/child.pia
Normal file
BIN
data/child.pia
Normal file
Binary file not shown.
32
include/SimpleEffect.h
Normal file
32
include/SimpleEffect.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "Effect.h"
|
||||
#include "prototypes.h"
|
||||
#include <cmath>
|
||||
|
||||
#define SE_CYCLE_COLORS 1 // Slowly cycle through the rainbow.
|
||||
#define SE_RANDOM_PIXEL_COLORS 2 // Every pixel gets a random color every frame.
|
||||
#define SE_ONLY_POSITIVE 4 // Only use colors, not white. This is equivalent to running your output through abs()
|
||||
#define SE_FADEOUT 8 // Fades the old image out. Returning 0 doesn't change the pixel's value.
|
||||
#define SE_RANDOM_STATIC_COLOR 16 // Sets a random static color at start of the effect.
|
||||
#define SE_DEBUG 32 // Prints debug messages.
|
||||
|
||||
class SimpleEffect : public Effect {
|
||||
protected:
|
||||
Window* window = &Window::window_full; // Use a full screen window per default.
|
||||
uint8_t _color = 0;
|
||||
uint16_t _flags;
|
||||
String _name;
|
||||
simple_effect_t _method;
|
||||
public:
|
||||
SimpleEffect(String name, uint16_t flags, simple_effect_t method): _name { name }, _method { method } {
|
||||
_flags = flags;
|
||||
if (_flags & SE_RANDOM_STATIC_COLOR) {
|
||||
_color = random8();
|
||||
_flags &= ~SE_CYCLE_COLORS & ~SE_RANDOM_PIXEL_COLORS;
|
||||
}
|
||||
};
|
||||
void loop(uint16_t ms) override;
|
||||
String get_name() { return _name; };
|
||||
boolean can_be_shown_with_clock() { return true; }
|
||||
|
||||
};
|
@ -53,4 +53,5 @@ public:
|
||||
void blur_row(uint8_t y, fract8 intensity);
|
||||
void blur_columns(fract8 intensity);
|
||||
void blur_column(uint8_t x, fract8 intensity);
|
||||
void fill_with_checkerboard();
|
||||
};
|
||||
|
@ -37,6 +37,7 @@
|
||||
#define MQTT_REPORT_METRICS // Whether to report metrics via MQTT. Disable if unwanted.
|
||||
#define MQTT_TOPIC_WEATHER "accuweather/pitrix/" // MQTT topic to listen for weather data. Must not start with a slash, but must end with one.
|
||||
#define MQTT_TOPIC_TIMER "alexa/timer"
|
||||
#define MQTT_TOPIC_HOMEASSISTANT "homeassistant"
|
||||
|
||||
#define HOSTNAME "pitrix-%08X" // Hostname of the ESP to use for OTA and MQTT client id. %08X will be replaced by the chip id.
|
||||
#define OTA_STARTUP_DELAY 10 // How many seconds to wait at startup. This is useful to prevent being unable to flash OTA by a bug in the code. Set to 0 to disable.
|
||||
@ -97,9 +98,9 @@
|
||||
} while (0);
|
||||
#else
|
||||
#define LOG(x, ...) Serial.printf(x, ##__VA_ARGS__);
|
||||
#define LOGln(x, ...) Serial.printf(x, ##__VA_ARGS__); Serial.println();
|
||||
#define LOGln(x, ...) { Serial.printf(x, ##__VA_ARGS__); Serial.println(); }
|
||||
#endif
|
||||
#define DBG(msg, ...) Serial.printf(msg, ##__VA_ARGS__); Serial.println();
|
||||
#define DBG(msg, ...) { Serial.printf(msg, ##__VA_ARGS__); Serial.println(); }
|
||||
#else
|
||||
#define LOG(x) do {} while(0);
|
||||
#define LOGln(x) do {} while(0);
|
||||
|
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Effect.h"
|
||||
#include "my_fastled.h"
|
||||
|
||||
class ConfettiEffect : public Effect {
|
||||
protected:
|
||||
virtual CRGB _getColor();
|
||||
public:
|
||||
void loop(uint16_t ms);
|
||||
boolean can_be_shown_with_clock();
|
||||
String get_name() override { return "confetti"; }
|
||||
};
|
||||
|
||||
class RandomConfettiEffect : public ConfettiEffect {
|
||||
protected:
|
||||
CRGB _getColor() override;
|
||||
String get_name() override { return "random_confetti"; }
|
||||
};
|
||||
|
@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Effect.h"
|
||||
#include "effect_clock.h"
|
||||
#include "effect_timer.h"
|
||||
#include "effects/clock.h"
|
||||
#include "effects/timer.h"
|
||||
|
||||
#define SIMPLE_EFFECT(name, use_in_cycle, flags, ...) {name, use_in_cycle, [](){ return new SimpleEffect(name, flags, [](double t, uint16_t i, uint8_t x, uint8_t y)->double __VA_ARGS__ ); }}
|
||||
|
||||
struct EffectEntry {
|
||||
const char* name;
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "Effect.h"
|
||||
#include "prototypes.h"
|
||||
#include "my_fastled.h"
|
||||
#include "Animation.h"
|
||||
#include "../Animation.h"
|
||||
|
||||
class AnimationEffect : public Effect {
|
||||
private:
|
@ -18,12 +18,4 @@ protected:
|
||||
public:
|
||||
virtual void loop(uint16_t ms);
|
||||
String get_name() override { return "big_clock"; }
|
||||
};
|
||||
|
||||
class NightClockEffect : public BigClockEffect {
|
||||
private:
|
||||
CRGB _color_font = CRGB(0x440000);
|
||||
CRGB _color_colon = CRGB(0x000000);
|
||||
void _draw_border_pixel(accum88 pos, CRGB* color) { };
|
||||
CRGB _get_color_font() { return CRGB(0x440000); }
|
||||
};
|
||||
};
|
8
include/effects/night_clock.h
Normal file
8
include/effects/night_clock.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "Effect.h"
|
||||
|
||||
class NightClockEffect : public Effect {
|
||||
public:
|
||||
virtual void loop(uint16_t ms);
|
||||
String get_name() override { return "night_clock"; }
|
||||
};
|
30
include/effects/tpm2_net.h
Normal file
30
include/effects/tpm2_net.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "Effect.h"
|
||||
#include "prototypes.h"
|
||||
#include "my_fastled.h"
|
||||
#include "Window.h"
|
||||
#include "config.h"
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
class Tpm2NetEffect : public Effect {
|
||||
protected:
|
||||
Window* window = &Window::window_full;
|
||||
WiFiUDP _udp;
|
||||
uint16_t _pixel_index = 0;
|
||||
|
||||
void _parse_command(uint16_t size, uint8_t packet_number);
|
||||
void _parse_data(uint16_t size, uint8_t packet_number);
|
||||
void _respond(uint8_t* data, uint8_t len);
|
||||
void _respond_ack();
|
||||
void _respond_with_data(uint8_t* data, uint8_t len);
|
||||
void _respond_unknown_command();
|
||||
unsigned long _last_packet_at = 0;
|
||||
|
||||
public:
|
||||
Tpm2NetEffect();
|
||||
virtual ~Tpm2NetEffect();
|
||||
virtual void loop(uint16_t ms);
|
||||
bool can_be_shown_with_clock();
|
||||
String get_name() override { return "tpm2.net"; }
|
||||
};
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "my_fastled.h"
|
||||
|
||||
extern uint8_t baseHue;
|
||||
extern char hostname[30];
|
||||
@ -31,3 +32,5 @@ typedef struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} Coords;
|
||||
|
||||
typedef std::function<double(double, uint16_t, uint8_t, uint8_t)> simple_effect_t;
|
35
src/SimpleEffect.cpp
Normal file
35
src/SimpleEffect.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include "SimpleEffect.h"
|
||||
|
||||
void SimpleEffect::loop(uint16_t ms) {
|
||||
if (_flags & SE_FADEOUT) window->fadeToBlackBy(3);
|
||||
double t = 0.001 * millis();
|
||||
for(uint8_t x=0; x<window->width; x++) for(uint8_t y=0; y<window->height; y++) {
|
||||
uint16_t i = y*window->width + x;
|
||||
double r = _method(t, i, x, y);
|
||||
//if (i==0) Serial.printf("t=%f i=%d x=%d y=%d => r=%f, abs(r)=%d\n", t, i, x, y, r, abs(r)*255);
|
||||
if ((_flags & SE_DEBUG) && i==17) Serial.printf("t=%f i=%d x=%d y=%d => r=%f, abs(r*255)=%d\n", t, i, x, y, r, (int)abs(r*255));
|
||||
if ((_flags & SE_FADEOUT) && r==0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Clamp r between -1.0 and +1.0
|
||||
if (r<-1.0) {
|
||||
r = -1.0;
|
||||
} else if (r>1.0) {
|
||||
r = 1.0;
|
||||
}
|
||||
|
||||
if (_flags & SE_ONLY_POSITIVE) {
|
||||
r = abs(r);
|
||||
}
|
||||
|
||||
CRGB color;
|
||||
if (_flags & SE_RANDOM_PIXEL_COLORS) {
|
||||
color = CHSV(random8(), 255, abs(r*255));
|
||||
} else {
|
||||
color = CHSV(_flags & SE_CYCLE_COLORS ? baseHue : _color, r<0?0:255, abs(r*255));
|
||||
}
|
||||
|
||||
window->setPixel(x, y, &color);
|
||||
}
|
||||
}
|
@ -272,3 +272,14 @@ void Window::_subpixel_render(uint8_t x, uint8_t y, CRGB* color, SubpixelRenderi
|
||||
case SUBPIXEL_RENDERING_SET: setPixel(x, y, color); break;
|
||||
}
|
||||
}
|
||||
|
||||
void Window::fill_with_checkerboard() {
|
||||
CRGB pink(0xFF00FF);
|
||||
CRGB black(0x000000);
|
||||
uint8_t s = (uint8_t)(millis() / 1000);
|
||||
for(int x=0; x<this->width; x++) {
|
||||
for(int y=0; y<this->height; y++) {
|
||||
this->setPixel(x, y, ((x+y+s) % 2)?&pink:&black);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +0,0 @@
|
||||
#include "effect_confetti.h"
|
||||
#include "config.h"
|
||||
#include "functions.h"
|
||||
#include "prototypes.h"
|
||||
|
||||
void ConfettiEffect::loop(uint16_t ms) {
|
||||
window->fadeToBlackBy(3);
|
||||
for (int i=0; i<settings.effects.confetti.pixels_per_loop; i++) {
|
||||
CRGB color = _getColor();
|
||||
window->addPixelColor(random16(LED_COUNT), &color);
|
||||
}
|
||||
}
|
||||
|
||||
CRGB ConfettiEffect::_getColor() {
|
||||
return CHSV(baseHue + random8(64), 255, 255);
|
||||
}
|
||||
|
||||
CRGB RandomConfettiEffect::_getColor() {
|
||||
return CHSV(random8(), 255, 255);
|
||||
}
|
||||
|
||||
boolean ConfettiEffect::can_be_shown_with_clock() { return true; };
|
125
src/effects.cpp
125
src/effects.cpp
@ -1,30 +1,32 @@
|
||||
#include "effects.h"
|
||||
#include "config.h"
|
||||
#include "my_fastled.h"
|
||||
#include "effect_bell.h"
|
||||
#include "effect_sinematrix3.h"
|
||||
#include "effect_big_clock.h"
|
||||
#include "effect_clock.h"
|
||||
#include "effect_static.h"
|
||||
#include "effect_animation.h"
|
||||
#include "effect_dynamic.h"
|
||||
#include "effect_matrix.h"
|
||||
#include "effect_twirl.h"
|
||||
#include "effect_cycle.h"
|
||||
#include "effect_confetti.h"
|
||||
#include "effect_snake.h"
|
||||
#include "effect_fire.h"
|
||||
#include "effect_firework.h"
|
||||
#include "effect_gol.h"
|
||||
#include "effect_pixelclock.h"
|
||||
#include "effect_dvd.h"
|
||||
#include "effect_analogclock.h"
|
||||
#include "effect_sines.h"
|
||||
#include "effect_marquee.h"
|
||||
#include "effect_blur2d.h"
|
||||
#include "effect_tv_static.h"
|
||||
#include "effect_lightspeed.h"
|
||||
#include "effect_diamond.h"
|
||||
#include "effects/bell.h"
|
||||
#include "effects/sinematrix3.h"
|
||||
#include "effects/big_clock.h"
|
||||
#include "effects/clock.h"
|
||||
#include "effects/static.h"
|
||||
#include "effects/animation.h"
|
||||
#include "effects/dynamic.h"
|
||||
#include "effects/matrix.h"
|
||||
#include "effects/twirl.h"
|
||||
#include "effects/cycle.h"
|
||||
#include "effects/snake.h"
|
||||
#include "effects/fire.h"
|
||||
#include "effects/firework.h"
|
||||
#include "effects/gol.h"
|
||||
#include "effects/pixelclock.h"
|
||||
#include "effects/dvd.h"
|
||||
#include "effects/analogclock.h"
|
||||
#include "effects/sines.h"
|
||||
#include "effects/marquee.h"
|
||||
#include "effects/blur2d.h"
|
||||
#include "effects/tv_static.h"
|
||||
#include "effects/lightspeed.h"
|
||||
#include "effects/diamond.h"
|
||||
#include "effects/tpm2_net.h"
|
||||
#include "SimpleEffect.h"
|
||||
#include "effects/night_clock.h"
|
||||
|
||||
Effect* current_effect;
|
||||
|
||||
@ -33,41 +35,48 @@ TimerEffect effect_timer;
|
||||
|
||||
// We're using 0 instead of false to get a better visual difference between true and false.
|
||||
EffectEntry effects[] = {
|
||||
/* 0 */ {"sinematrix3", true, [](){ return new Sinematrix3Effect(); }},
|
||||
/* 1 */ {"big_clock", true, [](){ return new BigClockEffect(); }},
|
||||
/* 2 */ {"clock", 0, [](){ return new ClockEffect(); }},
|
||||
/* 3 */ {"bell", 0, [](){ return AnimationEffect::Blinker("/bell.pia", 300, 0xFFFF00); }},
|
||||
/* 4 */ {"off", 0, [](){ return new StaticEffect(0x000000); }},
|
||||
/* 5 */ {"single_dynamic", true, [](){ return new SingleDynamicEffect(); }},
|
||||
/* 6 */ {"multi_dynamic", true, [](){ return new MultiDynamicEffect(); }},
|
||||
/* 7 */ {"big_dynamic", true, [](){ return new BigDynamicEffect(); }},
|
||||
/* 8 */ {"matrix", true, [](){ return new MatrixEffect(); }},
|
||||
/* 9 */ {"random_matrix", true, [](){ return new RandomMatrixEffect(); }},
|
||||
/* 10 */ {"rainbow_matrix", true, [](){ return new RainbowMatrixEffect(); }},
|
||||
/* 11 */ {"cycle", 0, [](){ return new CycleEffect(); }},
|
||||
/* 12 */ {"twirl", true, [](){ return new TwirlEffect(); }},
|
||||
/* 13 */ {"confetti", true, [](){ return new ConfettiEffect(); }},
|
||||
/* 14 */ {"random_confetti", true, [](){ return new RandomConfettiEffect(); }},
|
||||
/* 15 */ {"snake", true, [](){ return new SnakeEffect(); }},
|
||||
/* 16 */ {"firework", true, [](){ return new FireworkEffect(); }},
|
||||
/* 17 */ {"gol", true, [](){ return new GolEffect(); }},
|
||||
/* 18 */ {"pixel_clock", 0, [](){ return new PixelClockEffect(); }},
|
||||
/* 19 */ {"dvd", true, [](){ return new DvdEffect(); }},
|
||||
/* 20 */ {"analog_clock", 0, [](){ return new AnalogClockEffect(); }},
|
||||
/* 21 */ {"sines", true, [](){ return new SinesEffect(); }},
|
||||
/* 22 */ {"blur2d", true, [](){ return new Blur2DEffect(); }},
|
||||
/* 23 */ {"marquee", 0, [](){ return new MarqueeEffect(); }},
|
||||
/* 24 */ {"night_clock", 0, [](){ return new NightClockEffect(); }},
|
||||
/* 25 */ {"tv_static", 0, [](){ return new TvStaticEffect(); }},
|
||||
/* 26 */ {"sinematrix3_rainbow", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_RAINBOW); }},
|
||||
/* 27 */ {"sinematrix3_purplefly", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_PURPLEFLY); }},
|
||||
/* 28 */ {"lightspeed", true, [](){ return new LightspeedEffect(); }},
|
||||
/* 29 */ {"koopa", 0, [](){ return new AnimationEffect("/koopa.pia"); }},
|
||||
/* 30 */ {"cake", 0, [](){ return new AnimationEffect("/cake.pia"); }},
|
||||
/* 31 */ {"kid", 0, [](){ return new AnimationEffect("/kid.pia"); }},
|
||||
/* 32 */ {"diamond", true, [](){ return new DiamondEffect(); }},
|
||||
/* 0 */ {"sinematrix3", true, [](){ return new Sinematrix3Effect(); }},
|
||||
/* 1 */ {"big_clock", true, [](){ return new BigClockEffect(); }},
|
||||
/* 2 */ {"clock", 0, [](){ return new ClockEffect(); }},
|
||||
/* 3 */ {"bell", 0, [](){ return AnimationEffect::Blinker("/bell.pia", 300, 0xFFFF00); }},
|
||||
/* 4 */ {"off", 0, [](){ return new StaticEffect(0x000000); }},
|
||||
/* 5 */ {"single_dynamic", true, [](){ return new SingleDynamicEffect(); }},
|
||||
/* 6 */ {"multi_dynamic", true, [](){ return new MultiDynamicEffect(); }},
|
||||
/* 7 */ {"big_dynamic", true, [](){ return new BigDynamicEffect(); }},
|
||||
/* 8 */ {"matrix", true, [](){ return new MatrixEffect(); }},
|
||||
/* 9 */ {"random_matrix", true, [](){ return new RandomMatrixEffect(); }},
|
||||
/* 10 */ {"rainbow_matrix", true, [](){ return new RainbowMatrixEffect(); }},
|
||||
/* 11 */ {"cycle", 0, [](){ return new CycleEffect(); }},
|
||||
/* 12 */ {"twirl", true, [](){ return new TwirlEffect(); }},
|
||||
/* 13 */ SIMPLE_EFFECT("confetti", true, SE_CYCLE_COLORS | SE_FADEOUT, {return random8()>252?1:0;}),
|
||||
/* 14 */ SIMPLE_EFFECT("rainbow_confetti", true, SE_RANDOM_PIXEL_COLORS | SE_FADEOUT, {return random8()>252?1:0;}),
|
||||
/* 15 */ {"snake", true, [](){ return new SnakeEffect(); }},
|
||||
/* 16 */ {"firework", true, [](){ return new FireworkEffect(); }},
|
||||
/* 17 */ {"gol", true, [](){ return new GolEffect(); }},
|
||||
/* 18 */ {"pixel_clock", 0, [](){ return new PixelClockEffect(); }},
|
||||
/* 19 */ {"dvd", true, [](){ return new DvdEffect(); }},
|
||||
/* 20 */ {"analog_clock", 0, [](){ return new AnalogClockEffect(); }},
|
||||
/* 21 */ {"sines", true, [](){ return new SinesEffect(); }},
|
||||
/* 22 */ {"blur2d", true, [](){ return new Blur2DEffect(); }},
|
||||
/* 23 */ {"marquee", 0, [](){ return new MarqueeEffect(); }},
|
||||
/* 24 */ {"night_clock", 0, [](){ return new NightClockEffect(); }},
|
||||
/* 25 */ {"tv_static", 0, [](){ return new TvStaticEffect(); }},
|
||||
/* 26 */ {"sinematrix3_rainbow", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_RAINBOW); }},
|
||||
/* 27 */ {"sinematrix3_purplefly", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_PURPLEFLY); }},
|
||||
/* 28 */ {"lightspeed", true, [](){ return new LightspeedEffect(); }},
|
||||
/* 29 */ {"koopa", 0, [](){ return new AnimationEffect("/koopa.pia"); }},
|
||||
/* 30 */ {"cake", 0, [](){ return new AnimationEffect("/cake.pia"); }},
|
||||
/* 31 */ {"child", 0, [](){ return AnimationEffect::Blinker("/child.pia", 300, 0xFFFF00); }},
|
||||
/* 32 */ {"diamond", true, [](){ return new DiamondEffect(); }},
|
||||
/* 33 */ {"tpm2.net", 0, [](){ return new Tpm2NetEffect(); }},
|
||||
/* 34 */ SIMPLE_EFFECT("slow_blinking", true, SE_CYCLE_COLORS, {return sin(t + (x+1)*(y+1)*i);} ),
|
||||
/* 35 */ SIMPLE_EFFECT("upwave", true, SE_CYCLE_COLORS, {return (cos(t+y/2));} ),
|
||||
/* 36 */ SIMPLE_EFFECT("centerwave", true, SE_CYCLE_COLORS, {return sin(t*2 - sqrt((x-4)*(x-4) + (y-7)*(y-7)));} ),
|
||||
/* 37 */ SIMPLE_EFFECT("sineline", true, SE_RANDOM_STATIC_COLOR, {return sin(x/2)-sin(x-t)-y+6;} ),
|
||||
/* 38 */ SIMPLE_EFFECT("barbershop", true, SE_RANDOM_STATIC_COLOR, {return 1*cos(0.8*i-t*5);} ),
|
||||
/* 39 */ SIMPLE_EFFECT("zigzag", true, SE_CYCLE_COLORS, { return cos(cos(x+y)-y*cos(t/8+x/16));} ),
|
||||
};
|
||||
const uint8_t effects_size = 33;
|
||||
const uint8_t effects_size = 40;
|
||||
|
||||
|
||||
Effect* select_effect(const char* name) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "effect_analogclock.h"
|
||||
#include "effects/analogclock.h"
|
||||
#include "my_fastled.h"
|
||||
#include "ntp.h"
|
||||
#include <time.h>
|
@ -1,4 +1,4 @@
|
||||
#include "effect_animation.h"
|
||||
#include "effects/animation.h"
|
||||
#include "functions.h"
|
||||
|
||||
AnimationEffect::AnimationEffect(const char* name, uint32_t bg, int x, int y) {
|
@ -1,6 +1,6 @@
|
||||
#include "Effect.h"
|
||||
#include "functions.h"
|
||||
#include "effect_bell.h"
|
||||
#include "effects/bell.h"
|
||||
#include "sprites.h"
|
||||
|
||||
void BellEffect::loop(uint16_t ms) {
|
@ -1,5 +1,5 @@
|
||||
#include "Effect.h"
|
||||
#include "effect_big_clock.h"
|
||||
#include "effects/big_clock.h"
|
||||
#include "fonts.h"
|
||||
#include <time.h>
|
||||
#include "settings.h"
|
@ -1,4 +1,4 @@
|
||||
#include "effect_blur2d.h"
|
||||
#include "effects/blur2d.h"
|
||||
Blur2DBlob::Blur2DBlob() {
|
||||
_x_freq = random16(6<<8, 15<<8);
|
||||
_y_freq = random16(6<<8, 15<<8);
|
@ -1,4 +1,4 @@
|
||||
#include "effect_clock.h"
|
||||
#include "effects/clock.h"
|
||||
#include <FastLED.h>
|
||||
#include "functions.h"
|
||||
#include "fonts.h"
|
@ -1,4 +1,4 @@
|
||||
#include "effect_cycle.h"
|
||||
#include "effects/cycle.h"
|
||||
#include "effects.h"
|
||||
|
||||
CycleEffect::CycleEffect() {
|
@ -1,4 +1,4 @@
|
||||
#include "effect_diamond.h"
|
||||
#include "effects/diamond.h"
|
||||
#include "my_fastled.h"
|
||||
|
||||
void DiamondEffect::loop(uint16_t ms) {
|
@ -1,4 +1,4 @@
|
||||
#include "effect_dvd.h"
|
||||
#include "effects/dvd.h"
|
||||
#include "my_fastled.h"
|
||||
|
||||
void DvdEffect::loop(uint16_t ms) {
|
@ -1,4 +1,4 @@
|
||||
#include "effect_dynamic.h"
|
||||
#include "effects/dynamic.h"
|
||||
#include "functions.h"
|
||||
#include "config.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "effect_fire.h"
|
||||
#include "effects/fire.h"
|
||||
#include "my_color_palettes.h"
|
||||
#include "config.h"
|
||||
#include "my_fastled.h"
|
@ -1,5 +1,5 @@
|
||||
// Based on https://gist.github.com/kriegsman/68929cbd1d6de4535b20
|
||||
#include "effect_firework.h"
|
||||
#include "effects/firework.h"
|
||||
|
||||
FireworkEffectDot::FireworkEffectDot(Window* w, FireworkEffect* e) {
|
||||
_window = w;
|
@ -1,4 +1,4 @@
|
||||
#include "effect_gol.h"
|
||||
#include "effects/gol.h"
|
||||
#include "my_fastled.h"
|
||||
|
||||
GolEffect::GolEffect() {
|
@ -1,4 +1,4 @@
|
||||
#include "effect_lightspeed.h"
|
||||
#include "effects/lightspeed.h"
|
||||
#include "config.h"
|
||||
#include "functions.h"
|
||||
#include "prototypes.h"
|
@ -1,4 +1,4 @@
|
||||
#include "effect_marquee.h"
|
||||
#include "effects/marquee.h"
|
||||
#include "fonts.h"
|
||||
|
||||
boolean MarqueeEffect::can_be_shown_with_clock() {
|
@ -1,4 +1,4 @@
|
||||
#include "effect_matrix.h"
|
||||
#include "effects/matrix.h"
|
||||
#include "my_color_palettes.h"
|
||||
#include "functions.h"
|
||||
|
26
src/effects/night_clock.cpp
Normal file
26
src/effects/night_clock.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include "Effect.h"
|
||||
#include "effects/night_clock.h"
|
||||
#include "fonts.h"
|
||||
#include <time.h>
|
||||
|
||||
void NightClockEffect::loop(uint16_t ms) {
|
||||
window->clear();
|
||||
time_t now;
|
||||
tm timeinfo;
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
uint8_t h = timeinfo.tm_hour;
|
||||
CRGB color = CRGB(0x440000);
|
||||
window->drawChar(&font5x7, 4<<8, 0<<8, '0' + (h / 10), &color);
|
||||
window->drawChar(&font5x7, 10<<8, 0<<8, '0' + (h % 10), &color);
|
||||
|
||||
uint8_t m = timeinfo.tm_min;
|
||||
window->drawChar(&font5x7, 4<<8, 9<<8, '0' + (m / 10), &color);
|
||||
window->drawChar(&font5x7, 10<<8, 9<<8, '0' + (m % 10), &color);
|
||||
|
||||
uint8_t s = timeinfo.tm_sec;
|
||||
if(s & 1) {
|
||||
window->setPixel(2, 11, &color);
|
||||
window->setPixel(2, 13, &color);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#include "effect_pixelclock.h"
|
||||
#include "effects/pixelclock.h"
|
||||
#include "ntp.h"
|
||||
|
||||
PixelClockEffect::PixelClockEffect() {
|
@ -1,4 +1,4 @@
|
||||
#include "effect_sinematrix3.h"
|
||||
#include "effects/sinematrix3.h"
|
||||
#include "prototypes.h"
|
||||
#include "functions.h"
|
||||
#include "Effect.h"
|
@ -1,4 +1,4 @@
|
||||
#include "effect_sines.h"
|
||||
#include "effects/sines.h"
|
||||
|
||||
SinesEffectSinus::SinesEffectSinus(Window* w) {
|
||||
_window = w;
|
@ -1,4 +1,4 @@
|
||||
#include "effect_snake.h"
|
||||
#include "effects/snake.h"
|
||||
#include "functions.h"
|
||||
|
||||
SnakeEffect::SnakeEffect() {
|
@ -1,4 +1,4 @@
|
||||
#include "effect_static.h"
|
||||
#include "effects/static.h"
|
||||
#include "functions.h"
|
||||
#include "my_fastled.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "effect_timer.h"
|
||||
#include "effects/timer.h"
|
||||
#include <FastLED.h>
|
||||
#include "functions.h"
|
||||
#include "fonts.h"
|
181
src/effects/tpm2_net.cpp
Normal file
181
src/effects/tpm2_net.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
#include "effects/tpm2_net.h"
|
||||
#include "my_fastled.h"
|
||||
|
||||
void Tpm2NetEffect::loop(uint16_t ms) {
|
||||
int packetsize = _udp.parsePacket();
|
||||
uint8_t data[255];
|
||||
uint8_t type = 0x00;
|
||||
if (packetsize > 0) {
|
||||
_last_packet_at = millis();
|
||||
DBG("TPM2.Net * Received %d bytes from %s", packetsize, _udp.remoteIP().toString().c_str());
|
||||
if (packetsize < 7) {
|
||||
LOGln("TPM2.Net * Packet is too short. Ignoring it.");
|
||||
return;
|
||||
}
|
||||
_udp.read(data, 6);
|
||||
if (data[0] != 0x9C) {
|
||||
LOGln("TPM2.Net * Block start byte is 0x%02X, expected 0x9C", data[0]);
|
||||
return;
|
||||
}
|
||||
if (data[1] == 0xC0) {
|
||||
DBG("TPM2.Net * Received a command packet.");
|
||||
type = 0xC0;
|
||||
} else if (data[1] == 0xDA) {
|
||||
DBG("TPM2.Net * Received a data packet.");
|
||||
type = 0xDA;
|
||||
} else {
|
||||
LOGln("TPM2.Net * Unexpected packet type 0x%02X, expected 0xC0 or 0xDA.", data[1]);
|
||||
}
|
||||
uint16_t framesize = (data[2]<<8) | data[3];
|
||||
uint8_t packet_number = data[4];
|
||||
//uint8_t packet_count = data[5];
|
||||
|
||||
if (packetsize != framesize + 7) {
|
||||
LOGln("TPM2.Net * Invalid packet size. Expected %d bytes, was %d bytes.", framesize+7, packetsize);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type==0xC0) {
|
||||
_parse_command(framesize, packet_number);
|
||||
} else if (type==0xDA) {
|
||||
_parse_data(framesize, packet_number);
|
||||
}
|
||||
} else if (_last_packet_at + 5000 < millis()) {
|
||||
window->fill_with_checkerboard();
|
||||
}
|
||||
}
|
||||
|
||||
void Tpm2NetEffect::_parse_command(uint16_t size, uint8_t packet_number) {
|
||||
if (packet_number!=0) {
|
||||
LOGln("TPM2.Net * Command packet with packet_number > 0 (%d). Ignoring it.", packet_number);
|
||||
return;
|
||||
}
|
||||
if (size < 2) {
|
||||
LOGln("TPM2.Net * Command packet need at least 2 data bytes.");
|
||||
return;
|
||||
}
|
||||
uint8_t ctrl = _udp.read();
|
||||
bool write = ctrl & 0x80;
|
||||
bool respond = ctrl & 0x40;
|
||||
uint8_t cmd = _udp.read();
|
||||
uint8_t data = 0;
|
||||
if (write) {
|
||||
if (size<3) {
|
||||
LOGln("TPM2.Net * Got a write command, but no data to write.");
|
||||
return;
|
||||
}
|
||||
data = _udp.read();
|
||||
}
|
||||
|
||||
if (cmd == 0x0A) { // Master Brightness
|
||||
if (write) {
|
||||
FastLED.setBrightness(data);
|
||||
} else {
|
||||
uint8_t data[1] = {FastLED.getBrightness()};
|
||||
_respond_with_data(data, 1);
|
||||
}
|
||||
} else if (cmd == 0x10 && !write) {
|
||||
uint16_t pixels = window->width * window->height;
|
||||
uint8_t data[2] = {(uint8_t)(pixels >> 8), (uint8_t)(pixels & 0xFF)};
|
||||
_respond_with_data(data, 2);
|
||||
} else {
|
||||
LOGln("TPM2.Net * Unknown command. write:%d, command:0x%02X", write, cmd);
|
||||
if (respond) {
|
||||
_respond_unknown_command();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tpm2NetEffect::_parse_data(uint16_t framesize, uint8_t packet_number) {
|
||||
if (packet_number==0) {
|
||||
_pixel_index=0;
|
||||
}
|
||||
uint8_t len;
|
||||
uint8_t data[3];
|
||||
CRGB color;
|
||||
while ((len = _udp.read(data, 3))==3) {
|
||||
// We got 3 bytes
|
||||
color.setRGB(data[0], data[1], data[2]);
|
||||
window->setPixelByIndex(_pixel_index, &color);
|
||||
_pixel_index++;
|
||||
}
|
||||
|
||||
/*
|
||||
bool dir_changed = false;
|
||||
|
||||
_x += _x_dir * settings.effects.dvd.speed;
|
||||
_y += _y_dir * settings.effects.dvd.speed;
|
||||
|
||||
if (_x <= 0) {
|
||||
_x = -_x;
|
||||
_x_dir = -_x_dir;
|
||||
dir_changed = true;
|
||||
//LOGln("speed: %d", settings.effects.dvd.speed);
|
||||
} else if (_x + (settings.effects.dvd.width << 8) >= (window->width << 8)) {
|
||||
_x -= 2*settings.effects.dvd.speed;
|
||||
_x_dir = -_x_dir;
|
||||
dir_changed = true;
|
||||
}
|
||||
|
||||
if (_y <= 0) {
|
||||
_y = -_y;
|
||||
_y_dir = -_y_dir;
|
||||
dir_changed = true;
|
||||
} else if (_y + (settings.effects.dvd.height << 8) >= (window->height << 8)) {
|
||||
_y -= 2*settings.effects.dvd.speed;
|
||||
_y_dir = -_y_dir;
|
||||
dir_changed = true;
|
||||
}
|
||||
|
||||
window->clear();
|
||||
|
||||
if (dir_changed) _color = (CRGB)CHSV(random8(), 255, 255);
|
||||
|
||||
for (int x=0; x<settings.effects.dvd.width; x++) for (int y=0; y<settings.effects.dvd.height; y++) {
|
||||
window->setSubPixel(_x + (x<<8), _y + (y<<8), (CRGB*)&_color);
|
||||
}
|
||||
for (int x=1; x<settings.effects.dvd.width; x++) for (int y=1; y<settings.effects.dvd.height; y++) {
|
||||
window->setPixel((_x>>8) + x, (_y>>8) + y, (CRGB*)&_color);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void Tpm2NetEffect::_respond(uint8_t* data, uint8_t len) {
|
||||
_udp.beginPacket(_udp.remoteIP(), 65442);
|
||||
_udp.write(data, len);
|
||||
_udp.endPacket();
|
||||
}
|
||||
|
||||
void Tpm2NetEffect::_respond_ack() {
|
||||
uint8_t data[8] = {0x9C, 0xAC, 0x00, 0x01, 0x00, 0x01, 0x00, 0x36};
|
||||
_respond(data, 8);
|
||||
}
|
||||
|
||||
void Tpm2NetEffect::_respond_unknown_command() {
|
||||
uint8_t data[8] = {0x9C, 0xAC, 0x00, 0x01, 0x00, 0x01, 0x02, 0x36};
|
||||
_respond(data, 8);
|
||||
}
|
||||
|
||||
void Tpm2NetEffect::_respond_with_data(uint8_t* dat, uint8_t len) {
|
||||
uint8_t data[8 + len];
|
||||
data[0] = 0x9C;
|
||||
data[1] = 0xAD;
|
||||
data[2] = (len+1)>>8;
|
||||
data[3] = (len+1)&0xFF;
|
||||
data[4] = 0x00;
|
||||
data[5] = 0x01;
|
||||
data[6] = 0x00;
|
||||
memcpy(&(data[7]), dat, len);
|
||||
data[8 + len - 1] = 0x36;
|
||||
_respond(data, 8 + len);
|
||||
}
|
||||
|
||||
bool Tpm2NetEffect::can_be_shown_with_clock() { return false; }
|
||||
|
||||
Tpm2NetEffect::Tpm2NetEffect() {
|
||||
_udp.begin(65506);
|
||||
}
|
||||
|
||||
Tpm2NetEffect::~Tpm2NetEffect() {
|
||||
_udp.stop();
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#include "effect_tv_static.h"
|
||||
#include "effects/tv_static.h"
|
||||
|
||||
void TvStaticEffect::loop(uint16_t ms) {
|
||||
//uint8_t dark_position = (millis() % settings.effects.tv_static.black_bar_speed) * _window->width / settings.effects.tv_static.black_bar_speed;
|
@ -1,4 +1,4 @@
|
||||
#include "effect_twirl.h"
|
||||
#include "effects/twirl.h"
|
||||
#include "functions.h"
|
||||
|
||||
boolean TwirlEffect::can_be_shown_with_clock() { return true; };
|
22
src/mqtt.cpp
22
src/mqtt.cpp
@ -23,7 +23,7 @@ void mqtt_callback(char* original_topic, byte* pl, unsigned int length) {
|
||||
pl[length] = '\0';
|
||||
String payload((char*)pl);
|
||||
String topic (original_topic);
|
||||
if (topic.equals(MQTT_TOPIC "log") || topic.equals(MQTT_TOPIC "status") || topic.startsWith(MQTT_TOPIC "metrics")) {
|
||||
if (topic.equals(MQTT_TOPIC "log") || topic.equals(MQTT_TOPIC "status") || topic.equals(MQTT_TOPIC "status_details") || topic.startsWith(MQTT_TOPIC "metrics")) {
|
||||
// Return our own messages
|
||||
return;
|
||||
}
|
||||
@ -98,15 +98,33 @@ void mqtt_callback(char* original_topic, byte* pl, unsigned int length) {
|
||||
|
||||
boolean mqtt_connect() {
|
||||
LOGln("MQTT * Connecting to MQTT server with client id %s", hostname);
|
||||
mqtt_client.setBufferSize(350);
|
||||
if (mqtt_client.connect(hostname, MQTT_USER, MQTT_PASS, MQTT_TOPIC "status", 0, true, "OFFLINE", true)) {
|
||||
LOGln("MQTT * Connected.");
|
||||
LOGln("Core * Flash chip id: 0x%X. Size: %d bytes. 'Real' size: %d bytes.", ESP.getFlashChipId(), ESP.getFlashChipSize(), ESP.getFlashChipRealSize());
|
||||
char buffer[40];
|
||||
snprintf(buffer, 40, "ONLINE %s %s", hostname, WiFi.localIP().toString().c_str());
|
||||
mqtt_client.publish(MQTT_TOPIC "status", buffer, true);
|
||||
mqtt_client.publish(MQTT_TOPIC "status", "ONLINE", true);
|
||||
mqtt_client.publish(MQTT_TOPIC "status_details", buffer, true);
|
||||
mqtt_client.subscribe(MQTT_TOPIC "+");
|
||||
mqtt_client.subscribe(MQTT_TOPIC_WEATHER "#");
|
||||
mqtt_client.subscribe(MQTT_TOPIC_TIMER);
|
||||
|
||||
#ifdef MQTT_TOPIC_HOMEASSISTANT
|
||||
// Set MQTT values for homeassistant auto device discovery
|
||||
String topic = MQTT_TOPIC_HOMEASSISTANT "/light/";
|
||||
topic += hostname;
|
||||
topic += "/config";
|
||||
String message = "{\"~\":\"" MQTT_TOPIC "\",\"opt\":1,\"avty_t\":\"~status\",\"pl_avail\":\"ONLINE\",\"pl_not_avail\":\"OFFLINE\",";
|
||||
message += "\"bri_cmd_t\": \"~brightness\",\"bri_scl\":255,\"fx_cmd_t\":\"~modus\",\"name\":\"Pitrix\",\"uniq_id\":\"";
|
||||
message += hostname;
|
||||
message += "\",";
|
||||
message += "\"stat_t\":\"~modus\",\"cmd_t\":\"~modus\",\"pl_on\":\"cycle\",\"pl_off\":\"night_clock\"}";
|
||||
mqtt_client.publish(topic.c_str(), message.c_str(), true);
|
||||
DBG("MQTT * Homeassistant data:");
|
||||
DBG("MQTT * Topic: %s", topic.c_str());
|
||||
DBG("MQTT * Data: %s", message.c_str());
|
||||
#endif
|
||||
}
|
||||
return mqtt_client.connected();
|
||||
}
|
||||
|
@ -2,16 +2,6 @@
|
||||
require 'websocket-eventmachine-client'
|
||||
require 'pp'
|
||||
|
||||
def rgb2ansi(r, g, b)
|
||||
if r==g && g==b
|
||||
return 16 if r<8
|
||||
return 231 if r>248
|
||||
return (((r - 8) / 247.0) * 24).round + 232
|
||||
end
|
||||
|
||||
return 16 + 36*(r/51.0).round + 6*(g/51.0).round + (b/51.0).round
|
||||
end
|
||||
|
||||
IP = ARGV[0]
|
||||
EFFECT = ARGV[1]
|
||||
uri = "ws://#{IP}:80/ws"
|
||||
@ -41,8 +31,7 @@ EM.run do
|
||||
str += "|"
|
||||
(0...width).each do |x|
|
||||
r, g, b = *data.shift(3)
|
||||
color_code = rgb2ansi(r, g, b)
|
||||
str += "\033[48;5;#{color_code}m "
|
||||
str += "\033[38;2;#{r};#{g};#{b}m●"
|
||||
end
|
||||
str += "\033[0m|\n"
|
||||
end
|
||||
|
18
src/wifi.cpp
18
src/wifi.cpp
@ -6,10 +6,20 @@
|
||||
void wifi_setup() {
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASS);
|
||||
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||||
Serial.println("WiFi * Connection Failed! Rebooting...");
|
||||
delay(5000);
|
||||
ESP.restart();
|
||||
uint8_t result;
|
||||
uint8_t counter = 0;
|
||||
while ((result = WiFi.waitForConnectResult()) != WL_CONNECTED) {
|
||||
counter++;
|
||||
if (counter > 100) {
|
||||
Serial.print("WiFi * Connection Failed! Last result was: ");
|
||||
Serial.print(result);
|
||||
Serial.println(" Rebooting...");
|
||||
delay(100);
|
||||
ESP.restart();
|
||||
}
|
||||
Serial.print("WiFi * Still waiting for WiFi to connect. This is loop number ");
|
||||
Serial.println(counter);
|
||||
delay(100);
|
||||
}
|
||||
Serial.println("WiFi * Ready");
|
||||
Serial.print("WiFi * IP address: ");
|
||||
|
Reference in New Issue
Block a user