Skip to content

Commit

Permalink
Case RGB LEDs - Bounty #22 (#1241)
Browse files Browse the repository at this point in the history
* Case RGBs, Bounty #22

First attempt, going to see if this works locally but this is very similar to the turbo led code

* Update LED count for case RGBs, change default white to green

* Added configs for Open Core0 and Open Core0 WASD! Happy Holidays Train!!

* Fix for led index

* Update app.js
  • Loading branch information
arntsonl authored Dec 27, 2024
1 parent fcca934 commit eede7e2
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 3 deletions.
9 changes: 9 additions & 0 deletions configs/OpenCore0/BoardConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@
#define PLED4_PIN 27
#define PLED_COLOR ColorGreen

#define TURBO_LED_INDEX 28
#define TURBO_LED_TYPE PLED_TYPE_RGB
#define TURBO_LED_COLOR ColorRed

#define CASE_RGB_TYPE CASE_RGB_TYPE_STATIC
#define CASE_RGB_INDEX 29
#define CASE_RGB_COUNT 20
#define CASE_RGB_COLOR ColorGreen

#define HAS_I2C_DISPLAY 1
#define I2C0_ENABLED 1
#define I2C0_PIN_SDA 0
Expand Down
10 changes: 9 additions & 1 deletion configs/OpenCore0WASD/BoardConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,17 @@
#define PLED2_PIN 14
#define PLED3_PIN 15
#define PLED4_PIN 16

#define PLED_COLOR ColorGreen

#define TURBO_LED_INDEX 17
#define TURBO_LED_TYPE PLED_TYPE_RGB
#define TURBO_LED_COLOR ColorRed

#define CASE_RGB_TYPE CASE_RGB_TYPE_STATIC
#define CASE_RGB_INDEX 18
#define CASE_RGB_COUNT 20
#define CASE_RGB_COLOR ColorGreen

#define HAS_I2C_DISPLAY 1
#define I2C0_ENABLED 1
#define I2C0_PIN_SDA 0
Expand Down
16 changes: 16 additions & 0 deletions headers/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@
#define PLED_COLOR ColorWhite // White
#endif

#ifndef CASE_RGB_TYPE
#define CASE_RGB_TYPE CASE_RGB_TYPE_NONE
#endif

#ifndef CASE_RGB_INDEX
#define CASE_RGB_INDEX -1
#endif

#ifndef CASE_RGB_COLOR
#define CASE_RGB_COLOR ColorGreen // Green
#endif

#ifndef CASE_RGB_COUNT
#define CASE_RGB_COUNT 0
#endif

static inline bool isValidPin(int32_t pin) {
int32_t numBank0GPIOS = NUM_BANK0_GPIOS;
return pin >= 0 && pin < numBank0GPIOS; }
Expand Down
5 changes: 5 additions & 0 deletions proto/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,11 @@ message LEDOptions
optional int32 pledIndex2 = 33;
optional int32 pledIndex3 = 34;
optional int32 pledIndex4 = 35;

optional CaseRGBType caseRGBType = 36;
optional int32 caseRGBIndex = 37;
optional uint32 caseRGBColor = 38;
optional uint32 caseRGBCount = 39;
};

// This has to be kept in sync with AnimationOptions in AnimationStation.hpp
Expand Down
8 changes: 8 additions & 0 deletions proto/enums.proto
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,14 @@ enum PLEDType
PLED_TYPE_RGB = 1;
};

enum CaseRGBType
{
option (nanopb_enumopt).long_names = false;

CASE_RGB_TYPE_NONE = -1;
CASE_RGB_TYPE_STATIC = 0;
};

enum ForcedSetupMode
{
option (nanopb_enumopt).long_names = false;
Expand Down
18 changes: 16 additions & 2 deletions src/addons/neopicoleds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,7 @@ void NeoPicoLEDAddon::setup()
gamepad->auxState.playerID.enabled = true;
gamepad->auxState.sensors.statusLight.enabled = true;

if ( ledOptions.pledType == PLED_TYPE_RGB ||
turboOptions.turboLedType == PLED_TYPE_RGB) {
if ( ledOptions.pledType == PLED_TYPE_RGB ) {
neoPLEDs = new NeoPicoPlayerLEDs();
}

Expand Down Expand Up @@ -318,6 +317,17 @@ void NeoPicoLEDAddon::process()
}
}

// Case RGB LEDs for a single static color go here
if ( ledOptions.caseRGBType == CASE_RGB_TYPE_STATIC &&
ledOptions.caseRGBIndex >= 0 &&
ledOptions.caseRGBCount > 0 ) {
float brightness = as.GetBrightnessX();
uint32_t colorVal = ((RGB)ledOptions.caseRGBColor).value(neopico->GetFormat(), brightness);
for(int i = 0; i < ledOptions.caseRGBCount; i++) {
frame[ledOptions.caseRGBIndex+i] = colorVal;
}
}

neopico->SetFrame(frame);
neopico->Show();
AnimationStore.save();
Expand Down Expand Up @@ -621,6 +631,10 @@ void NeoPicoLEDAddon::configureLEDs()
if (turboOptions.turboLedType == PLED_TYPE_RGB)
ledCount += 1;

if (ledOptions.caseRGBType == CASE_RGB_TYPE_STATIC ) {
ledCount += ledOptions.caseRGBCount;
}

// Remove the old neopico (config can call this)
delete neopico;
neopico = new NeoPico(ledOptions.dataPin, ledCount, static_cast<LEDFormat>(ledOptions.ledFormat));
Expand Down
5 changes: 5 additions & 0 deletions src/config_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,11 @@ void ConfigUtils::initUnsetPropertiesWithDefaults(Config& config)
INIT_UNSET_PROPERTY(config.ledOptions, pledIndex3, PLED3_PIN);
INIT_UNSET_PROPERTY(config.ledOptions, pledIndex4, PLED4_PIN);

INIT_UNSET_PROPERTY(config.ledOptions, caseRGBType, CASE_RGB_TYPE);
INIT_UNSET_PROPERTY(config.ledOptions, caseRGBIndex, CASE_RGB_INDEX);
INIT_UNSET_PROPERTY(config.ledOptions, caseRGBColor, static_cast<uint32_t>(CASE_RGB_COLOR.r) << 16 | static_cast<uint32_t>(CASE_RGB_COLOR.g) << 8 | static_cast<uint32_t>(CASE_RGB_COLOR.b));
INIT_UNSET_PROPERTY(config.ledOptions, caseRGBCount, CASE_RGB_COUNT);

// animationOptions
INIT_UNSET_PROPERTY(config.animationOptions, baseAnimationIndex, LEDS_BASE_ANIMATION_INDEX);
INIT_UNSET_PROPERTY(config.animationOptions, brightness, LEDS_BRIGHTNESS);
Expand Down
8 changes: 8 additions & 0 deletions src/configs/webconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,10 @@ std::string setLedOptions()
readDoc(ledOptions.pledIndex3, doc, "pledIndex3");
readDoc(ledOptions.pledIndex4, doc, "pledIndex4");
readDoc(ledOptions.pledColor, doc, "pledColor");
readDoc(ledOptions.caseRGBType, doc, "caseRGBType");
readDoc(ledOptions.caseRGBIndex, doc, "caseRGBIndex");
readDoc(ledOptions.caseRGBCount, doc, "caseRGBCount");
readDoc(ledOptions.caseRGBColor, doc, "caseRGBColor");

Storage::getInstance().save(true);
return serialize_json(doc);
Expand Down Expand Up @@ -855,6 +859,10 @@ std::string getLedOptions()
writeDoc(doc, "pledIndex3", ledOptions.pledIndex3);
writeDoc(doc, "pledIndex4", ledOptions.pledIndex4);
writeDoc(doc, "pledColor", ((RGB)ledOptions.pledColor).value(LED_FORMAT_RGB));
writeDoc(doc, "caseRGBType", ledOptions.caseRGBType);
writeDoc(doc, "caseRGBIndex", ledOptions.caseRGBIndex);
writeDoc(doc, "caseRGBCount", ledOptions.caseRGBCount);
writeDoc(doc, "caseRGBColor", ((RGB)ledOptions.caseRGBColor).value(LED_FORMAT_RGB));

return serialize_json(doc);
}
Expand Down
4 changes: 4 additions & 0 deletions www/server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ app.get('/api/getLedOptions', (req, res) => {
pledIndex3: 14,
pledIndex4: 15,
pledColor: 65280,
caseRGBType: 0,
caseRGBColor: 65280,
caseRGBIndex: -1,
caseRGBCount: 0,
turnOffWhenSuspended: 0,
});
});
Expand Down
11 changes: 11 additions & 0 deletions www/src/Locales/en/LedConfig.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ export default {
'pled-type-rgb': 'RGB',
'pled-color-label': 'RGB PLED Color',
},
case: {
'header-text': 'Case RGB LEDs',
'sub-header-text':
'For Case RGB LEDs, set a starting index and the case RGB count. The index must be after the last LED button defined but can be before or after the player LEDs and turbo LED.',
'case-index-label': 'RGB LED Index',
'case-count-label': 'RGB LED Count',
'case-type-label': 'Color Type',
'case-type-off': 'Off',
'case-type-static': 'Static',
'case-color-label': 'Case RGB Color',
},
'pled-pin-label': 'PLED #{{pin}} Pin',
'pled-index-label': 'PLED #{{index}} Index',
'rgb-order': {
Expand Down
107 changes: 107 additions & 0 deletions www/src/Pages/LEDConfigPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ const defaultValue = {
pledIndex3: -1,
pledIndex4: -1,
pledColor: '#00ff00',
caseRGBType: 0,
caseRGBIndex: -1,
caseRGBCount: 0,
caseRGBColor: '#00ff00',
ledButtonMap: {},
};

Expand Down Expand Up @@ -137,6 +141,21 @@ const schema = yup.object().shape({
.label('PLED Index 4')
.validateMinWhenEqualTo('pledType', 1, 0),
turnOffWhenSuspended: yup.number().label('Turn Off When Suspended'),
caseRGBType: yup.number().required().label('Case RGB Type'),
caseRGBColor: yup.string().label('Case RGB LEDs').validateColor(),
caseRGBCount: yup
.number()
.required()
.positive()
.integer()
.min(0)
.max(100)
.label('Case RGB Count'),
caseRGBIndex: yup
.number()
.label('Case RGB Index')
.min(-1)
.max(100),
ledButtonMap: yup.object(),
});

Expand Down Expand Up @@ -272,6 +291,7 @@ export default function LEDConfigPage() {
const data = {
...values,
pledColor: hexToInt(values.pledColor || '#000000'),
caseRGBColor: hexToInt(values.caseRGBColor || '#000000'),
};

const success = await WebApi.setLedOptions(data);
Expand Down Expand Up @@ -646,6 +666,93 @@ export default function LEDConfigPage() {
</p>
</Form.Group>
</Section>
<Section title={t('LedConfig:case.header-text')}>
<Form.Group as={Col}>
<Row>
<FormSelect
label={t('LedConfig:case.case-type-label')}
name="caseRGBType"
className="form-select-sm"
groupClassName="col-sm-2 mb-3"
value={values.caseRGBType}
error={errors.caseRGBType}
isInvalid={errors.caseRGBType}
onChange={(e) =>
setFieldValue('caseRGBType', parseInt(e.target.value))
}
>
<option value="-1" defaultValue={true}>
{t('LedConfig:case.case-type-off')}
</option>
<option value="0">
{t('LedConfig:case.case-type-static')}
</option>
</FormSelect>
<FormControl
type="number"
name="caseRGBIndex"
hidden={parseInt(values.caseRGBType) === -1}
label={t('LedConfig:case.case-index-label')}
className="form-control-sm"
groupClassName="col-sm-2 mb-3"
value={values.caseRGBIndex}
error={errors.caseRGBIndex}
isInvalid={errors.caseRGBIndex}
onChange={(e) =>
setFieldValue('caseRGBIndex', parseInt(e.target.value))
}
min={0}
/>
<FormControl
type="number"
name="caseRGBCount"
hidden={parseInt(values.caseRGBType) === -1}
label={t('LedConfig:case.case-count-label')}
className="form-control-sm"
groupClassName="col-sm-2 mb-3"
value={values.caseRGBCount}
error={errors.caseRGBCount}
isInvalid={errors.caseRGBCount}
onChange={(e) =>
setFieldValue('caseRGBCount', parseInt(e.target.value))
}
min={0}
/>
<FormControl
label={t('LedConfig:case.case-color-label')}
hidden={parseInt(values.caseRGBType) !== 0}
name="caseRGBColor"
className="form-control-sm"
groupClassName="col-sm-2 mb-3"
value={values.caseRGBColor}
error={errors.caseRGBColor}
isInvalid={errors.caseRGBColor}
onBlur={handleBlur}
onClick={toggleRgbPledPicker}
onChange={(e) => {
handleChange(e);
setShowPicker(false);
}}
/>
<ColorPicker
name="caseRGBColor"
types={[{ value: values.caseRGBColor }]}
onChange={(c) => setFieldValue('caseRGBColor', c)}
onDismiss={() => setShowPicker(false)}
placement="top"
presetColors={LEDColors.map((c) => ({
title: c.name,
color: c.value,
}))}
show={showPicker}
target={colorPickerTarget}
></ColorPicker>
</Row>
<p >
{t('LedConfig:case.sub-header-text')}
</p>
</Form.Group>
</Section>
<Button type="submit">{t('Common:button-save-label')}</Button>
{saveMessage ? <span className="alert">{saveMessage}</span> : null}
<FormContext
Expand Down
1 change: 1 addition & 0 deletions www/src/Services/WebApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ async function getLedOptions(setLoading) {
setLoading(false);

response.data.pledColor = rgbIntToHex(response.data.pledColor) || '#ffffff';
response.data.caseRGBColor = rgbIntToHex(response.data.caseRGBColor) || '#ffffff';

return response.data;
} catch (error) {
Expand Down

0 comments on commit eede7e2

Please sign in to comment.