Skip to content

Commit

Permalink
+Plug S: Support for Neopixel Status LEDs (#1601)
Browse files Browse the repository at this point in the history
  • Loading branch information
markirb authored Jan 10, 2025
1 parent c126c4e commit eb47707
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 4 deletions.
4 changes: 4 additions & 0 deletions mos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,8 @@ conds:
${build_vars.ESP_IDF_SDKCONFIG_OPTS}
CONFIG_FREERTOS_UNICORE=y
CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
libs:
- location: https://github.com/mongoose-os-libs/neopixel
cdefs:
LED_GPIO: 25
LED_ON: 1
Expand All @@ -638,6 +640,8 @@ conds:
- ["sw1.state_led_en", 1]
- ["bl0937.power_coeff", "f", 0, {title: "BL0937 counts -> watts conversion coefficient"}]
- ["bl0937.power_coeff", 1.64358469] # (16 + 1010 + 1935) / (9.55 + 617 + 1175)
- ["led.color_on", "i", 0x00FF00, {title: "LED color when on"}]
- ["led.color_off", "i", 0xFF0000, {title: "LED color when off"}]

- when: build_vars.MODEL == "ShellyPlusRGBWPM"
apply:
Expand Down
10 changes: 6 additions & 4 deletions src/ShellyPlusPlugS/shelly_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "shelly_main.hpp"
#include "shelly_output.hpp"
#include "shelly_pm_bl0937.hpp"
#include "shelly_statusled.hpp"
#include "shelly_sys_led_btn.hpp"
#include "shelly_temp_sensor_ntc.hpp"

Expand All @@ -30,10 +31,11 @@ void CreatePeripherals(std::vector<std::unique_ptr<Input>> *inputs,
std::unique_ptr<TempSensor> *sys_temp) {
outputs->emplace_back(new OutputPin(1, 4, 1));

// TODO: GPIO 25 and 26 are actually neopixel lights, and are not used as such
// currently
outputs->emplace_back(new OutputPin(2, 25, 1));
outputs->emplace_back(new OutputPin(3, 26, 1));
outputs->emplace_back(new StatusLED(2, 25, 2, MGOS_NEOPIXEL_ORDER_GRB,
nullptr, mgos_sys_config_get_led()));
outputs->emplace_back(new StatusLED(3, 26, 2, MGOS_NEOPIXEL_ORDER_GRB,
FindOutput(2),
mgos_sys_config_get_led()));

std::unique_ptr<PowerMeter> pm(
new BL0937PowerMeter(1, 10 /* CF */, 22 /* CF1 */, 19 /* SEL */, 2,
Expand Down
77 changes: 77 additions & 0 deletions src/shelly_statusled.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) Shelly-HomeKit Contributors
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "shelly_statusled.hpp"

#ifdef MGOS_CONFIG_HAVE_LED

namespace shelly {

StatusLED::StatusLED(int id, int pin, int num_pixel,
enum mgos_neopixel_order pixel_type, Output *chained_led,
const struct mgos_config_led *cfg)
: Output(id),
pin_(pin),
num_pixel_(num_pixel),
chained_led_(chained_led),
cfg_(cfg) {
pixel_ = mgos_neopixel_create(pin_, num_pixel_, pixel_type);
value_ = false;
}

StatusLED::~StatusLED() {
mgos_neopixel_free(pixel_);
}

bool StatusLED::GetState() {
return value_;
}

int StatusLED::pin() const {
return pin_;
}

struct rgb {
int r;
int g;
int b;
};

Status StatusLED::SetState(bool on, const char *source) {
if (chained_led_ != nullptr) {
chained_led_->SetState(on, source);
}
value_ = on;
// get color from config
struct rgb colorOn = {(cfg_->color_on >> 16) & 0xFF,
(cfg_->color_on >> 8) & 0xFF,
(cfg_->color_on >> 0) & 0xFF};
struct rgb colorOff = {(cfg_->color_off >> 16) & 0xFF,
(cfg_->color_off >> 8) & 0xFF,
(cfg_->color_off >> 0) & 0xFF};

struct rgb color = on ? colorOn : colorOff;

for (int i = 0; i < num_pixel_; i++) {
mgos_neopixel_set(pixel_, i, color.r, color.b, color.g);
}
mgos_neopixel_show(pixel_);
return Status::OK();
}

} // namespace shelly

#endif
66 changes: 66 additions & 0 deletions src/shelly_statusled.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (c) Shelly-HomeKit Contributors
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "mgos_config.h"

#ifdef MGOS_CONFIG_HAVE_LED

#pragma once

#include "shelly_output.hpp"

#include "mgos_neopixel.h"

namespace shelly {

class StatusLED : public Output {
public:
StatusLED(int id, int pin, int num_pixel, enum mgos_neopixel_order pixel_type,
Output *chained_led, const struct mgos_config_led *cfg);
virtual ~StatusLED();

// Output interface impl.
bool GetState() override;
Status SetState(bool on, const char *source) override;
Status SetStatePWM(float duty, const char *source) override {
return Status::UNIMPLEMENTED();
};
Status Pulse(bool on, int duration_ms, const char *source) override {
return Status::UNIMPLEMENTED();
};
void SetInvert(bool out_invert) override{};
int pin() const;

protected:
private:
const int pin_;
const int num_pixel_;

bool value_;

struct mgos_neopixel *pixel_;

Output *chained_led_;

const struct mgos_config_led *cfg_;

StatusLED(const StatusLED &other) = delete;
};

} // namespace shelly

#endif

0 comments on commit eb47707

Please sign in to comment.