Skip to content

Commit 166b2b1

Browse files
committed
Done - full API implementation for pixels.proto, needs doxygen and testing
1 parent e3d5526 commit 166b2b1

File tree

5 files changed

+164
-30
lines changed

5 files changed

+164
-30
lines changed

src/components/pixels/controller.cpp

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,33 @@ PixelsController::~PixelsController() {
4444
*/
4545
/**************************************************************************/
4646
bool PixelsController::Handle_Pixels_Add(pb_istream_t *stream) {
47-
// Attempt to decode the istream
47+
// Attempt to decode the istream into a PixelsAdd message
4848
if (!_pixels_model->DecodePixelsAdd(stream))
4949
return false;
50-
// Get the decoded message
5150
wippersnapper_pixels_PixelsAdd *msg_add = _pixels_model->GetPixelsAddMsg();
5251
_pixel_strands[_num_strands] = new PixelsHardware();
5352

54-
// TODO: Call ConfigureStrand()!
53+
// Configure the pixel strand
5554
bool did_init = false;
56-
did_init = _pixel_strands[_num_strands]->ConfigureStrand(
55+
did_init = _pixel_strands[_num_strands]->AddStrand(
5756
msg_add->pixels_type, msg_add->pixels_ordering, msg_add->pixels_num,
5857
msg_add->pixels_brightness, msg_add->pixels_pin_data,
5958
msg_add->pixels_pin_dotstar_clock);
6059
if (!did_init)
6160
WS_DEBUG_PRINTLN("[pixels] Failed to create strand!");
62-
// TODO: Implement the wippersnapper_pixels_PixelsAdded message back to the
63-
// broker here
61+
62+
// Publish PixelsAdded message to the broker
63+
if (!_pixels_model->EncodePixelsAdded(msg_add->pixels_pin_data, did_init)) {
64+
WS_DEBUG_PRINTLN("[pixels]: Failed to encode PixelsAdded message!");
65+
return false;
66+
}
67+
if (!WsV2.PublishSignal(wippersnapper_signal_DeviceToBroker_pixels_added_tag,
68+
_pixels_model->GetPixelsAddedMsg())) {
69+
WS_DEBUG_PRINTLN("[pixels]: Unable to publish PixelsAdded message!");
70+
return false;
71+
}
72+
73+
return true;
6474
}
6575

6676
/**************************************************************************/
@@ -71,7 +81,25 @@ bool PixelsController::Handle_Pixels_Add(pb_istream_t *stream) {
7181
@returns True if successful, False otherwise
7282
*/
7383
/**************************************************************************/
74-
bool PixelsController::Handle_Pixels_Write(pb_istream_t *stream) {}
84+
bool PixelsController::Handle_Pixels_Write(pb_istream_t *stream) {
85+
// Decode the PixelsWrite message
86+
if (!_pixels_model->DecodePixelsWrite(stream)) {
87+
WS_DEBUG_PRINTLN("[pixels]: Failed to decode PixelsWrite message!");
88+
return false;
89+
}
90+
wippersnapper_pixels_PixelsWrite *msg_write =
91+
_pixels_model->GetPixelsWriteMsg();
92+
uint16_t pin_data = atoi(msg_write->pixels_pin_data + 1);
93+
uint16_t idx = GetStrandIndex(pin_data);
94+
if (idx == -1) {
95+
WS_DEBUG_PRINTLN("[pixels]: Failed to find strand index!");
96+
return false;
97+
}
98+
99+
// Call hardware to fill the strand
100+
_pixel_strands[idx]->FillStrand(msg_write->pixels_color);
101+
return true;
102+
}
75103

76104
/**************************************************************************/
77105
/*!
@@ -81,4 +109,40 @@ bool PixelsController::Handle_Pixels_Write(pb_istream_t *stream) {}
81109
@returns True if successful, False otherwise
82110
*/
83111
/**************************************************************************/
84-
bool PixelsController::Handle_Pixels_Remove(pb_istream_t *stream) {}
112+
bool PixelsController::Handle_Pixels_Remove(pb_istream_t *stream) {
113+
// Decode the PixelsRemove message
114+
if (!_pixels_model->DecodePixelsRemove(stream)) {
115+
WS_DEBUG_PRINTLN("[pixels]: Failed to decode PixelsRemove message!");
116+
return false;
117+
}
118+
wippersnapper_pixels_PixelsRemove *msg_remove =
119+
_pixels_model->GetPixelsRemoveMsg();
120+
121+
uint16_t pin_data = atoi(msg_remove->pixels_pin_data + 1);
122+
uint16_t idx = GetStrandIndex(pin_data);
123+
if (idx == -1) {
124+
WS_DEBUG_PRINTLN("[pixels]: Failed to find strand index!");
125+
return false;
126+
}
127+
128+
// Call hardware to deinitialize the strand
129+
_pixel_strands[idx]->RemoveStrand();
130+
return true;
131+
}
132+
133+
/**************************************************************************/
134+
/*!
135+
@brief Handles a request to update the pixel strands
136+
@param pin_data
137+
The desired data pin
138+
@returns Desired strand index, -1 if not found.
139+
*/
140+
/**************************************************************************/
141+
uint16_t PixelsController::GetStrandIndex(uint16_t pin_data) {
142+
for (int i = 0; i < _num_strands; i++) {
143+
if (_pixel_strands[i]->GetPinData() == pin_data) {
144+
return i;
145+
}
146+
}
147+
return -1;
148+
}

src/components/pixels/controller.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class PixelsController {
4343
PixelsModel *_pixels_model = nullptr; ///< Pointer to the model class
4444
PixelsHardware *_pixel_strands[MAX_PIXEL_STRANDS] = {nullptr}; ///< Pointer to the hardware class
4545
uint8_t _num_strands; ///< Number of pixel strands
46+
uint16_t GetStrandIndex(uint16_t pin_data);
4647
};
4748
extern Wippersnapper_V2 WsV2; ///< Wippersnapper V2 instance
4849
#endif // WS_PIXELS_CONTROLLER_H

src/components/pixels/hardware.cpp

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,13 @@ bool PixelsHardware::AddDotStar(uint16_t num_pixels, uint16_t pin_data,
7575
WS_DEBUG_PRINT(pin_clock);
7676
}
7777

78-
bool PixelsHardware::ConfigureStrand(wippersnapper_pixels_PixelsType type,
79-
wippersnapper_pixels_PixelsOrder order,
80-
uint32_t num_pixels, uint32_t brightness,
81-
const char *pin_data,
82-
const char *pin_clock) {
78+
bool PixelsHardware::AddStrand(wippersnapper_pixels_PixelsType type,
79+
wippersnapper_pixels_PixelsOrder order,
80+
uint32_t num_pixels, uint32_t brightness,
81+
const char *pin_data, const char *pin_clock) {
8382
_type = type;
8483
// Convert the pin string to an integer
8584
uint16_t p_data = atoi(pin_data + 1);
86-
// Generics, TODO
87-
8885
if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_NEOPIXEL) {
8986
if (!AddNeoPixel(num_pixels, p_data, GetStrandOrderNeoPixel(order),
9087
(uint8_t)brightness)) {
@@ -99,7 +96,7 @@ bool PixelsHardware::ConfigureStrand(wippersnapper_pixels_PixelsType type,
9996
return false;
10097
}
10198
} else {
102-
// TODO! Signal!!!
99+
WS_DEBUG_PRINTLN("[pixels] Unknown pixel type!");
103100
return false;
104101
}
105102
return true;
@@ -114,7 +111,32 @@ bool PixelsHardware::ConfigureStrand(wippersnapper_pixels_PixelsType type,
114111
32-bit color value
115112
*/
116113
/**************************************************************************/
117-
void PixelsHardware::SetPixelColor(uint8_t pin_data, uint32_t color) {}
114+
void PixelsHardware::FillStrand(uint32_t color) {
115+
// Apply gamma correction to match IO Web
116+
uint32_t color_gamma = ApplyGammaCorrection(color);
117+
WS_DEBUG_PRINT("[pixels] Filling strand with color: ");
118+
WS_DEBUG_PRINT(color_gamma, HEX);
119+
if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_NEOPIXEL) {
120+
_neopixel->fill(color_gamma);
121+
_neopixel->show();
122+
} else if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_DOTSTAR) {
123+
_dotstar->fill(color_gamma);
124+
_dotstar->show();
125+
} else {
126+
WS_DEBUG_PRINTLN("[pixels] Unknown pixel type!");
127+
}
128+
}
129+
130+
uint32_t PixelsHardware::ApplyGammaCorrection(uint32_t color) {
131+
if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_NEOPIXEL) {
132+
return _neopixel->gamma32(color);
133+
} else if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_DOTSTAR) {
134+
return _dotstar->gamma32(color);
135+
} else {
136+
WS_DEBUG_PRINTLN("[pixels] Unknown pixel type!");
137+
return color;
138+
}
139+
}
118140

119141
/**************************************************************************/
120142
/*!
@@ -123,7 +145,25 @@ void PixelsHardware::SetPixelColor(uint8_t pin_data, uint32_t color) {}
123145
Data pin for the pixel strand
124146
*/
125147
/**************************************************************************/
126-
void PixelsHardware::deinit(uint8_t pin_data) {}
148+
void PixelsHardware::RemoveStrand() {
149+
if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_NEOPIXEL) {
150+
if (_neopixel != nullptr) {
151+
delete _neopixel;
152+
_neopixel = nullptr;
153+
}
154+
} else if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_DOTSTAR) {
155+
if (_dotstar != nullptr) {
156+
delete _dotstar;
157+
_dotstar = nullptr;
158+
}
159+
} else {
160+
WS_DEBUG_PRINTLN("[pixels] Unknown pixel type!");
161+
}
162+
163+
// Optionally re-init the status pixel for reuse by app.
164+
if (getStatusNeoPixelPin() == _pin_data && !WsV2.lockStatusNeoPixelV2)
165+
initStatusLED();
166+
}
127167

128168
/**************************************************************************/
129169
/**

src/components/pixels/hardware.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,14 @@ class PixelsHardware {
3939
public:
4040
PixelsHardware();
4141
~PixelsHardware();
42-
bool ConfigureStrand(wippersnapper_pixels_PixelsType type,
43-
wippersnapper_pixels_PixelsOrder order,
44-
uint32_t num_pixels, uint32_t brightness,
45-
const char *pin_data, const char *pin_clock);
42+
bool AddStrand(wippersnapper_pixels_PixelsType type,
43+
wippersnapper_pixels_PixelsOrder order, uint32_t num_pixels,
44+
uint32_t brightness, const char *pin_data,
45+
const char *pin_clock);
4646
uint16_t GetPinData();
47-
void SetPixelColor(uint8_t pin_data, uint32_t color);
48-
void deinit(uint8_t pin_data);
47+
void FillStrand(uint32_t color);
48+
void RemoveStrand();
49+
4950
private:
5051
Adafruit_NeoPixel *_neopixel = nullptr; ///< Used for NeoPixel pixel strands
5152
Adafruit_DotStar *_dotstar = nullptr; ///< Used for DotStar pixel strands
@@ -57,5 +58,6 @@ class PixelsHardware {
5758
wippersnapper_pixels_PixelsOrder order, uint8_t brightness);
5859
neoPixelType GetStrandOrderNeoPixel(wippersnapper_pixels_PixelsOrder order);
5960
uint8_t GetStrandOrderDotStar(wippersnapper_pixels_PixelsOrder order);
61+
uint32_t ApplyGammaCorrection(uint32_t color);
6062
};
6163
#endif // WS_PIXELS_HARDWARE_H

src/components/pixels/model.cpp

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,18 @@
2222
*/
2323
/**************************************************************************/
2424
PixelsModel::PixelsModel() {
25-
_msg_pixels_add = wippersnapper_pixels_PixelsAdd_init_zero;
26-
_msg_pixels_remove = wippersnapper_pixels_PixelsRemove_init_zero;
27-
_msg_pixels_write = wippersnapper_pixels_PixelsWrite_init_zero;
28-
_msg_pixels_added = wippersnapper_pixels_PixelsAdded_init_zero;
25+
_msg_pixels_add = wippersnapper_pixels_PixelsAdd_init_zero;
26+
_msg_pixels_remove = wippersnapper_pixels_PixelsRemove_init_zero;
27+
_msg_pixels_write = wippersnapper_pixels_PixelsWrite_init_zero;
28+
_msg_pixels_added = wippersnapper_pixels_PixelsAdded_init_zero;
2929
}
3030

3131
/**************************************************************************/
3232
/*!
3333
@brief Destructs a PixelsModel object
3434
*/
3535
/**************************************************************************/
36-
PixelsModel::~PixelsModel() {
37-
}
36+
PixelsModel::~PixelsModel() {}
3837

3938
/**************************************************************************/
4039
/*!
@@ -45,6 +44,9 @@ PixelsModel::~PixelsModel() {
4544
*/
4645
/**************************************************************************/
4746
bool PixelsModel::DecodePixelsAdd(pb_istream_t *stream) {
47+
_msg_pixels_add = wippersnapper_pixels_PixelsAdd_init_zero;
48+
return pb_decode(stream, wippersnapper_pixels_PixelsAdd_fields,
49+
&_msg_pixels_add);
4850
}
4951

5052
/**************************************************************************/
@@ -54,6 +56,7 @@ bool PixelsModel::DecodePixelsAdd(pb_istream_t *stream) {
5456
*/
5557
/**************************************************************************/
5658
wippersnapper_pixels_PixelsAdd *PixelsModel::GetPixelsAddMsg() {
59+
return &_msg_pixels_add;
5760
}
5861

5962
/**************************************************************************/
@@ -65,6 +68,9 @@ wippersnapper_pixels_PixelsAdd *PixelsModel::GetPixelsAddMsg() {
6568
*/
6669
/**************************************************************************/
6770
bool PixelsModel::DecodePixelsRemove(pb_istream_t *stream) {
71+
_msg_pixels_remove = wippersnapper_pixels_PixelsRemove_init_zero;
72+
return pb_decode(stream, wippersnapper_pixels_PixelsRemove_fields,
73+
&_msg_pixels_remove);
6874
}
6975

7076
/**************************************************************************/
@@ -74,6 +80,7 @@ bool PixelsModel::DecodePixelsRemove(pb_istream_t *stream) {
7480
*/
7581
/**************************************************************************/
7682
wippersnapper_pixels_PixelsRemove *PixelsModel::GetPixelsRemoveMsg() {
83+
return &_msg_pixels_remove;
7784
}
7885

7986
/**************************************************************************/
@@ -85,6 +92,9 @@ wippersnapper_pixels_PixelsRemove *PixelsModel::GetPixelsRemoveMsg() {
8592
*/
8693
/**************************************************************************/
8794
bool PixelsModel::DecodePixelsWrite(pb_istream_t *stream) {
95+
_msg_pixels_write = wippersnapper_pixels_PixelsWrite_init_zero;
96+
return pb_decode(stream, wippersnapper_pixels_PixelsWrite_fields,
97+
&_msg_pixels_write);
8898
}
8999

90100
/**************************************************************************/
@@ -94,6 +104,7 @@ bool PixelsModel::DecodePixelsWrite(pb_istream_t *stream) {
94104
*/
95105
/**************************************************************************/
96106
wippersnapper_pixels_PixelsWrite *PixelsModel::GetPixelsWriteMsg() {
107+
return &_msg_pixels_write;
97108
}
98109

99110
/**************************************************************************/
@@ -107,6 +118,21 @@ wippersnapper_pixels_PixelsWrite *PixelsModel::GetPixelsWriteMsg() {
107118
*/
108119
/**************************************************************************/
109120
bool PixelsModel::EncodePixelsAdded(char *pin_data, bool success) {
121+
// Fill the message
122+
_msg_pixels_added = wippersnapper_pixels_PixelsAdded_init_zero;
123+
_msg_pixels_added.is_success = success;
124+
strncpy(_msg_pixels_added.pixels_pin_data, pin_data,
125+
sizeof(_msg_pixels_added.pixels_pin_data));
126+
127+
// Encode it!
128+
size_t sz_msg;
129+
if (!pb_get_encoded_size(&sz_msg, wippersnapper_pixels_PixelsAdded_fields,
130+
&_msg_pixels_added))
131+
return false;
132+
uint8_t buf[sz_msg];
133+
pb_ostream_t msg_stream = pb_ostream_from_buffer(buf, sizeof(buf));
134+
return pb_encode(&msg_stream, wippersnapper_pixels_PixelsAdded_fields,
135+
&_msg_pixels_added);
110136
}
111137

112138
/**************************************************************************/
@@ -116,4 +142,5 @@ bool PixelsModel::EncodePixelsAdded(char *pin_data, bool success) {
116142
*/
117143
/**************************************************************************/
118144
wippersnapper_pixels_PixelsAdded *PixelsModel::GetPixelsAddedMsg() {
145+
return &_msg_pixels_added;
119146
}

0 commit comments

Comments
 (0)