Skip to content

Commit

Permalink
initial support for ESP32-C3, ESP32-S2, ESP32-S3 (#112)
Browse files Browse the repository at this point in the history
- ***Breaking changes***: requires `Glow Worm Luciferin` (v5.11.8)
- **[Added support for ESP32-C3, ESP32-S2, ESP32-S3](https://github.com/sblantipodi/firefly_luciferin/wiki/Compatible-Hardware).** 
Lolin ESP32-C3, Lolin ESP32-S2 and Lolin ESP32-S3 are now fully compatible with the existing [Luciferin Official PCB](https://github.com/sblantipodi/firefly_luciferin/wiki/Ready-to-print-PCB).
TinyS2 and TinyS3 are now compatible with the existing [Luciferin Module](https://github.com/sblantipodi/firefly_luciferin/wiki/Ready-to-print-PCB#upgradeble-pcb-using-luciferin-modules) for the [Luciferin Official PCB](https://github.com/sblantipodi/firefly_luciferin/wiki/Ready-to-print-PCB).
Closes [#46](sblantipodi/glow_worm_luciferin#46).
- Added **[support for DotStar LED strips](https://github.com/sblantipodi/firefly_luciferin/wiki/Compatible-Hardware#led-strip-ws2812bsk6812apa102sk9812-5v).** Closes [#42](sblantipodi/glow_worm_luciferin#42).
- Added the possibility to **[configure GPIOs for Relay, Button and LDR](https://github.com/sblantipodi/firefly_luciferin/wiki/Supported-GPIO-and-Baud-Rate)**.
- Added the possibility to **[switch profiles through MQTT](https://github.com/sblantipodi/firefly_luciferin/wiki/Home-Automation-configs)**. Closes [#110](#110).
- Added **[BRG, RBG, GBR color order](https://github.com/sblantipodi/firefly_luciferin/wiki/RGB-and-RGBW-support#how-to-change-color-order)** support.
- Improved [power saving](https://github.com/sblantipodi/firefly_luciferin/wiki/Power-saving-features) mode. Closes [#107](#107).
- Improved existing [light effects](https://github.com/sblantipodi/firefly_luciferin/wiki/Light-effects).
- Improved [aspect ratio auto detection](https://github.com/sblantipodi/firefly_luciferin/wiki/Aspect-ratio), very dark scenes do not trigger an aspect ratio switch as there is no way to know which is the correct one. 
- IMAX 1.85:1 format now triggers the letterbox aspect ratio. 
- There is now a single [Web Installer](https://sblantipodi.github.io/glow_worm_luciferin/) for both stable and beta firmware.
- Reduced firmware footprint.
- Removed the hard limit on the maximum number of LEDs. You can now use as many LEDs as you want as long as your microcontroller has enough memory.
- Increased the priority of the capturing threads. This fixed a flickering issue that occurs while using the [smoothing effect (frame generation)](https://github.com/sblantipodi/firefly_luciferin/wiki/Smoothing-color-transitions) on Hybrid CPUs. Does not affect CPU load.
- UDP broadcast collision fix. Corrects weird behaviours when using two instances of Firefly Luciferin on two or more computers on the same network with UDP stream. 
- Configuring the [Web Interface](https://github.com/sblantipodi/firefly_luciferin/wiki/Remote-Access#luciferin-web-interface) no longer requires an Internet connection. Closes [#52](sblantipodi/glow_worm_luciferin#52)
- Fixed a bottleneck that reduced performance when driving many LEDs via USB. ESP32 was able to drive 500LEDs at 5FPS, now it can drive the same amount of LEDs at 30FPS.
- Fixed an issue that prevented a profile from changing the current framerate without pausing and restarting the capture.
- [Arduino Bootstrapper](https://github.com/sblantipodi/arduino_bootstrapper/releases) update (v.1.15.2).
  • Loading branch information
sblantipodi authored Aug 2, 2023
1 parent 49dbed5 commit 7ef5c43
Show file tree
Hide file tree
Showing 69 changed files with 1,076 additions and 504 deletions.
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ updates:
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
open-pull-requests-limit: 10
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ jobs:
echo $RELEASE_VERSION
echo ${{ env.RELEASE_VERSION }}
shell: bash
- name: Set up AdoptOpenJDK 17
- name: Set up AdoptOpenJDK 20
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
java-version: '20'
architecture: x64
- name: Install submodules
run: |
Expand Down Expand Up @@ -79,11 +79,11 @@ jobs:
run: |
echo $RELEASE_VERSION
echo ${{ env.RELEASE_VERSION }}
- name: Set up AdoptOpenJDK 17
- name: Set up AdoptOpenJDK 20
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
java-version: '20'
architecture: x64
- id: get-id
run: |
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ jobs:
echo $RELEASE_VERSION
echo ${{ env.RELEASE_VERSION }}
shell: bash
- name: Set up AdoptOpenJDK 17
- name: Set up AdoptOpenJDK 20
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
java-version: '20'
architecture: x64
- name: Install submodules
run: |
Expand Down Expand Up @@ -103,11 +103,11 @@ jobs:
run: |
echo $RELEASE_VERSION
echo ${{ env.RELEASE_VERSION }}
- name: Set up AdoptOpenJDK 17
- name: Set up AdoptOpenJDK 20
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
java-version: '20'
architecture: x64
- id: get-id
run: |
Expand Down Expand Up @@ -162,11 +162,11 @@ jobs:
id=$(echo $RELEASE_VERSION | cut -dv -f2)
echo "id=$id" >> $GITHUB_OUTPUT
shell: bash
- name: Set up AdoptOpenJDK 17
- name: Set up AdoptOpenJDK 20
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
java-version: '20'
architecture: x64
- name: Set up Maven Settings for deploy
uses: s4u/[email protected]
Expand Down
Binary file modified data/img/ha_luciferin.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 33 additions & 6 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,38 @@

### In this release:

- ***Breaking changes***: requires `Glow Worm Luciferin` (v5.11.8)
- **Added support for ESP32-C3, ESP32-S2, ESP32-S3.**
Lolin ESP32-C3, Lolin ESP32-S2 and Lolin ESP32-S3 are now fully compatible with the existing Luciferin Official PCB.
TinyS2 and TinyS3 are now compatible with the existing Luciferin Module for the Luciferin Official PCB.
Closes [#46].
- Added **support for DotStar LED strips.** Closes [#42].
- Added the possibility to **configure GPIOs for Relay, Button and LDR**.
- Added the possibility to **switch profiles through MQTT**. Closes [#110].
- Added **BRG, RBG, GBR color order** support.
- Improved power saving mode. Closes [#107].
- Improved existing light effects.
- Improved aspect ratio auto detection, very dark scenes do not trigger an aspect ratio switch as there is no way to
know which is the correct one.
- IMAX 1.85:1 format now triggers the letterbox aspect ratio.
- There is now a single Web Installer for both stable and beta firmware.
- Reduced firmware footprint.
- Removed the hard limit on the maximum number of LEDs. You can now use as many LEDs as you want as long as your
microcontroller has enough memory.
- Increased the priority of the capturing threads. This fixed a flickering issue that occurs while using the smoothing
effect (frame generation) on Hybrid CPUs. Does not affect CPU load.
- UDP broadcast collision fix. Corrects weird behaviours when using two instances of Firefly Luciferin on two or more
computers on the same network with UDP stream.
- Configuring the Web Interface no longer requires an Internet connection. Closes [#52].
- Fixed a bottleneck that reduced performance when driving many LEDs via USB. ESP32 was able to drive 500LEDs at 5FPS,
now it can drive the same amount of LEDs at 30FPS.
- Fixed an issue that prevented a profile from changing the current framerate without pausing and restarting the
capture.
- Arduino Bootstrapper update (v.1.15.2).


### In the previous release:

- ***Breaking changes***: requires `Glow Worm Luciferin` (v5.10.6).
- **Added a smoothing feature that is used to smooth the transitions from one color to another**,
this is particularly useful to reduce eye strain with contents that produces fast flashing like fast peaced games or
Expand All @@ -40,9 +72,4 @@
- Web Installer now presents an option to install beta or previous version of the Glow Worm Luciferin firmware.
- Improved log level configurability.
- Removed warnings in the Home Assistant logs.
- Arduino Bootstrapper update (v.1.14).

### In the previous release:

- ***Hotfix release:*** Fixed an issue that prevents 21:9 screen resolutions to correctly capture the screen. No
firmware upgrade needed.
- Arduino Bootstrapper update (v.1.14).
5 changes: 2 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@
<project.version>2.11.7</project.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17.0.2</java.version>
<java.fx.version>20.0.2</java.fx.version>
<javafx.maven.plugin.version>0.0.8</javafx.maven.plugin.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>20</maven.compiler.source>
<maven.compiler.target>20</maven.compiler.target>
<maven.compiler.plugin.version>3.11.0</maven.compiler.plugin.version>
<maven.assembly.version>3.6.0</maven.assembly.version>
<maven.shade.version>3.2.4</maven.shade.version>
Expand Down
22 changes: 19 additions & 3 deletions src/main/java/org/dpsoftware/FireflyLuciferin.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,13 @@ public class FireflyLuciferin extends Application implements SerialPortEventList
public static boolean communicationError = false;
public static Color colorInUse;
public static int gpio = 0; // 0 means not set, firmware discards this value
public static int colorOrder = 1; // 1 means GRB, 2 RGB, 3 BGR
public static int colorOrder = 0; // 1 means GRB, 2 RGB, 3 BGR
public static int ldrAction = 0; // 1 no action, 2 calibrate, 3 reset, 4 save
public static int fireflyEffect = 0;
public static int relayPin = -1;
public static int sbPin = -1;
public static int ldrPin = -1;
public static int gpioClockPin = 0;
public static boolean nightMode = false;
public static String version = "";
public static String minimumFirmwareVersion = "";
Expand Down Expand Up @@ -167,6 +171,7 @@ public FireflyLuciferin() {
hostServices = this.getHostServices();
powerSavingManager = new PowerSavingManager();
powerSavingManager.setLastFrameTime(LocalDateTime.now());
NativeExecutor.setHighPriorityThreads(config.getThreadPriority());
}

/**
Expand All @@ -193,13 +198,22 @@ private static void setNightBrightness(boolean tempNightMode) {

/**
* Set LED number, this can be changed on the fly.
* We are transferring byte via Serial, the maximum decimal number that can be represented with 1 byte is 255.
* Use a multiplier to set a much bigger number using only 2 bytes.
*
* @param ledMatrixInUse led matrix in use
*/
public static void setLedNumber(String ledMatrixInUse) {
ledNumber = CommonUtility.isSingleDeviceMultiScreen() ? MessageServer.totalLedNum : config.getLedMatrixInUse(ledMatrixInUse).size();
ledNumHighLowCount = ledNumber > Constants.SERIAL_CHUNK_SIZE ? Constants.SERIAL_CHUNK_SIZE - 1 : ledNumber - 1;
ledNumHighLowCountSecondPart = ledNumber > Constants.SERIAL_CHUNK_SIZE ? ledNumber - Constants.SERIAL_CHUNK_SIZE : 0;
int multiplier = (int) Math.floor((double) ledNumber / Constants.SERIAL_CHUNK_SIZE);
int lastPart = ledNumber - (Constants.SERIAL_CHUNK_SIZE * multiplier);
if (lastPart < 1) {
multiplier--;
ledNumHighLowCount = Constants.SERIAL_CHUNK_SIZE - 1;
} else {
ledNumHighLowCount = ledNumber > Constants.SERIAL_CHUNK_SIZE ? lastPart - 1 : ledNumber - 1;
}
ledNumHighLowCountSecondPart = ledNumber > Constants.SERIAL_CHUNK_SIZE ? multiplier : 0;
}

/**
Expand All @@ -208,6 +222,7 @@ public static void setLedNumber(String ledMatrixInUse) {
* @param args startup args
*/
public static void main(String[] args) {
profileArgs = Constants.DEFAULT;
if (args.length > 1) {
profileArgs = args[1];
}
Expand Down Expand Up @@ -241,6 +256,7 @@ public static void checkForNightMode() {
*/
private void setRuntimeLogLevel() {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
log.info("** Log level -> " + config.getRuntimeLogLevel() + " **");
loggerContext.getLogger(Constants.LOG_LEVEL_ROOT).setLevel(Level.toLevel(config.getRuntimeLogLevel()));
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/dpsoftware/JavaFXStarter.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
package org.dpsoftware;

import lombok.extern.slf4j.Slf4j;
import org.dpsoftware.config.Constants;
import org.dpsoftware.utilities.CommonUtility;

import java.util.Objects;

Expand Down Expand Up @@ -52,6 +54,7 @@ public static void main(String... args) {
}
whoAmI = Integer.parseInt(args[0]);
spawnInstances = false;
CommonUtility.sleepMilliseconds(Constants.SPAWN_INSTANCE_WAIT_START_DELAY);
} else {
log.info("Starting default instance");
}
Expand Down
83 changes: 29 additions & 54 deletions src/main/java/org/dpsoftware/NativeExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* A utility class for running native commands and get the results
Expand All @@ -55,27 +56,6 @@ public final class NativeExecutor {
public static boolean restartOnly = false;
public static boolean exitTriggered = false;

/**
* This is the real runner that return command output line by line.
* It waits for the output, don't use it if you don't need the result output.
*
* @param cmdToRunUsingArgs Command to run and args, in an array
* @return A list of string containing the output, empty list if command does not exist
*/
public static List<String> runNativeWaitForOutput(String[] cmdToRunUsingArgs) {
return runNative(cmdToRunUsingArgs, true);
}

/**
* This is the real runner that execute commands without waiting for the output.
* It doesn't wait for the output, use it if you don't need the result output.
*
* @param cmdToRunUsingArgs Command to run and args, in an array
*/
public static void runNativeNoWaitForOutput(String[] cmdToRunUsingArgs) {
runNative(cmdToRunUsingArgs, false);
}

/**
* This is the real runner that executes command.
* Don't use this method directly and prefer the runNativeWaitForOutput() or runNativeNoWaitForOutput() shortcut.
Expand All @@ -84,26 +64,21 @@ public static void runNativeNoWaitForOutput(String[] cmdToRunUsingArgs) {
* @param waitForOutput Example: If you need to exit the app you don't need to wait for the output or the app will not exit
* @return A list of string containing the output, empty list if command does not exist
*/
private static List<String> runNative(String[] cmdToRunUsingArgs, boolean waitForOutput) {
public static List<String> runNative(String[] cmdToRunUsingArgs, int waitForOutput) {
Process process;
ArrayList<String> cmdOutput = new ArrayList<>();
try {
if (cmdToRunUsingArgs.length > 1) {
process = Runtime.getRuntime().exec(cmdToRunUsingArgs);
} else {
process = Runtime.getRuntime().exec(cmdToRunUsingArgs[0]);
}
process = Runtime.getRuntime().exec(cmdToRunUsingArgs);
} catch (SecurityException | IOException e) {
log.info(CommonUtility.getWord(Constants.CANT_RUN_CMD), Arrays.toString(cmdToRunUsingArgs), e.getMessage());
return new ArrayList<>(0);
}
if (waitForOutput) {
if (waitForOutput > 0) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), Charset.defaultCharset()))) {
String line;
while ((line = reader.readLine()) != null) {
while (process.waitFor(waitForOutput, TimeUnit.MILLISECONDS) && (line = reader.readLine()) != null) {
cmdOutput.add(line);
}
process.waitFor();
} catch (IOException e) {
log.info(CommonUtility.getWord(Constants.NO_OUTPUT), Arrays.toString(cmdToRunUsingArgs), e.getMessage());
return new ArrayList<>(0);
Expand All @@ -121,24 +96,15 @@ private static List<String> runNative(String[] cmdToRunUsingArgs, boolean waitFo
* @param whoAmISupposedToBe instance #
*/
public static void spawnNewInstance(int whoAmISupposedToBe) {
String strToRun;
log.info("Installation path from spawn={}", getInstallationPath());
List<String> execCommand = new ArrayList<>();
if (NativeExecutor.isWindows()) {
String[] cmdToRun = getInstallationPath().split("\\\\");
StringBuilder command = new StringBuilder();
for (String str : cmdToRun) {
if (str.contains(" ")) {
command.append("\\" + "\"").append(str).append("\"");
} else {
command.append("\\").append(str);
}
}
command = new StringBuilder(command.substring(1));
strToRun = Constants.CMD_RUN + command + " " + whoAmISupposedToBe;
} else {
strToRun = getInstallationPath() + " " + whoAmISupposedToBe;
execCommand.add(Constants.CMD_SHELL_FOR_CMD_EXECUTION);
execCommand.add(Constants.CMD_PARAM_FOR_CMD_EXECUTION);
}
runNativeNoWaitForOutput(new String[]{strToRun});
execCommand.add(getInstallationPath());
execCommand.add(String.valueOf(whoAmISupposedToBe));
runNative(execCommand.toArray(String[]::new), Constants.SPAWN_INSTANCE_WAIT_DELAY);
}

/**
Expand All @@ -148,15 +114,10 @@ public static void spawnNewInstances() {
if (JavaFXStarter.spawnInstances && FireflyLuciferin.config.getMultiMonitor() > 1) {
if (FireflyLuciferin.config.getMultiMonitor() == 3) {
NativeExecutor.spawnNewInstance(1);
if ((FireflyLuciferin.config.getMultiMonitor() == 2) || (FireflyLuciferin.config.getMultiMonitor() == 3)) {
CommonUtility.sleepSeconds(1);
NativeExecutor.spawnNewInstance(2);
}
CommonUtility.sleepSeconds(1);
NativeExecutor.spawnNewInstance(2);
NativeExecutor.spawnNewInstance(3);
} else {
NativeExecutor.spawnNewInstance(1);
CommonUtility.sleepSeconds(1);
if (FireflyLuciferin.config.getMultiMonitor() == 2) {
NativeExecutor.spawnNewInstance(2);
}
Expand Down Expand Up @@ -184,9 +145,9 @@ public static void restartNativeInstance(String profileToUse) {
execCommand.add(getInstallationPath());
execCommand.add(String.valueOf(JavaFXStarter.whoAmI));
if (profileToUse != null) {
execCommand.add("\"" + profileToUse + "\"");
execCommand.add(profileToUse);
}
runNativeNoWaitForOutput(execCommand.toArray(String[]::new));
runNative(execCommand.toArray(String[]::new), 0);
if (CommonUtility.isSingleDeviceMultiScreen()) {
restartOnly = true;
}
Expand Down Expand Up @@ -348,7 +309,7 @@ static void exitOtherInstances() {
*/
public static boolean isScreensaverRunning() {
String[] scrCmd = {Constants.CMD_SHELL_FOR_CMD_EXECUTION, Constants.CMD_PARAM_FOR_CMD_EXECUTION, Constants.CMD_LIST_RUNNING_PROCESS};
List<String> scrProcess = runNativeWaitForOutput(scrCmd);
List<String> scrProcess = runNative(scrCmd, Constants.CMD_WAIT_DELAY);
return scrProcess.stream().filter(s -> s.contains(Constants.SCREENSAVER_EXTENSION)).findAny().orElse(null) != null;
}

Expand Down Expand Up @@ -388,4 +349,18 @@ public void deleteRegistryKey() {
}
}

/**
* Change thread priority to high = 128
*/
public static void setHighPriorityThreads(String priority) {
if (isWindows()) {
CommonUtility.delaySeconds(() -> {
log.info("Changing thread priority to -> " + priority);
String[] cmd = {Constants.CMD_POWERSHELL, Constants.CMD_SET_PRIORITY
.replace("{0}", String.valueOf(Enums.ThreadPriority.valueOf(priority).getValue()))};
NativeExecutor.runNative(cmd, 0);
}, 1);
}
}

}
Loading

0 comments on commit 7ef5c43

Please sign in to comment.