Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial #20

Merged
merged 56 commits into from
Jul 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
fffd826
Update issue templates
almostengr Feb 1, 2024
7a16805
Added files from FPP template
almostengr Feb 1, 2024
96e147b
Updated plugin information, repository links
almostengr Feb 1, 2024
d633662
Created pseudocode for worker; updated links in about
almostengr Feb 1, 2024
47bef89
Updated description
almostengr Feb 2, 2024
ceaee03
#3 send status; updated menu links, repository links
almostengr Apr 8, 2024
093011f
moved common logic to common.php; created settings.php
almostengr Apr 8, 2024
061f8e2
#14 #12 #3 updated settings form, worker
almostengr Apr 9, 2024
5c539a2
#3 created request object for server
almostengr Apr 25, 2024
63e6b1b
Refactored worker, created script for background proces
almostengr Apr 26, 2024
41e707b
Reorganized project; updated project name and url
almostengr Apr 29, 2024
2351c54
created tests
almostengr Apr 29, 2024
415aa89
Removed composer files; closed #8 status only sent when sequence chan…
almostengr May 31, 2024
79a63ee
added plugin json url to readme
almostengr May 31, 2024
85159da
#3 added environment option; #14 updated menu, method visibility
almostengr May 31, 2024
18ece2d
#15 set up composer, GH workflow for automated testing
almostengr May 31, 2024
2b6a4cc
#16 created automated tests
almostengr Jun 1, 2024
29524ee
#16 created automated tests
almostengr Jun 1, 2024
536c2f9
Merge remote-tracking branch 'refs/remotes/origin/initial' into initial
almostengr Jun 1, 2024
1077d77
Automated testing (#18)
almostengr Jun 1, 2024
b2ba0ad
removed code coverage option
almostengr Jun 1, 2024
d1fe529
#16 removed unused workflow
almostengr Jun 1, 2024
2cb9417
Updated plugin information
almostengr Jun 1, 2024
2d0d277
Updated install instructions; plugin information
almostengr Jun 1, 2024
f7be805
#16 added tests; moved worker call to separate file for testing
almostengr Jun 1, 2024
444cc17
updated workflows
almostengr Jun 2, 2024
380e150
Update daemon to stop logging errors after 5 failures to prevent fill…
almostengr Jun 3, 2024
a503100
Updated status response with next request; adjusted delays, method n…
almostengr Jun 3, 2024
e975271
updated method name, logic for posting status
almostengr Jun 3, 2024
4d04d26
Removed help directory, updated bug template for FPP
almostengr Jun 3, 2024
c43ed73
Updated beta environment URL
almostengr Jun 3, 2024
67a96e5
Updated plugin info URL
almostengr Jun 3, 2024
bd38b38
updated branch name
almostengr Jun 3, 2024
e1c01d8
Ignore swap files; added immediate and gracefull stop options
almostengr Jun 4, 2024
6abf66e
multiple updates and bug fixes
Jun 5, 2024
ddd686c
created commands for enabling and disabling requests
almostengr Jun 5, 2024
e4b70d7
Merge remote-tracking branch 'refs/remotes/origin/initial' into initial
almostengr Jun 5, 2024
970eeae
Updated file name; added command descriptions
almostengr Jun 5, 2024
227e87b
updated dependabot; added commands
almostengr Jun 6, 2024
4611b4e
Update BETA url, removed unused file
almostengr Jun 11, 2024
695683f
Updated test condition; log messages
almostengr Jun 11, 2024
8c1dffc
added link to help documentation
almostengr Jun 11, 2024
37f7957
update routes; code cleanup
almostengr Jun 16, 2024
13e1a90
Updated command descriptions and names
almostengr Jun 16, 2024
6609a2b
Refactor method; created install and uninstall scripts, constants; di…
almostengr Jun 20, 2024
da0c45c
Updated settings to use configuration file from server
almostengr Jun 25, 2024
e7daf25
Updated endspoints to website; modified workflow for daemon
almostengr Jul 9, 2024
6613d3e
refactored commands; modified sending sequences
almostengr Jul 15, 2024
e3ddcf7
cleaned up constants; updated logic for status and next request
almostengr Jul 16, 2024
ca7cd76
moved constants from functions; updated calls for admin sequence requ…
almostengr Jul 16, 2024
42f5c9e
Updated for jukebox selection; move to commands for worker funtionality
almostengr Jul 18, 2024
c53f0c5
Moved functionality to CommandHandlers
almostengr Jul 19, 2024
3b21078
closed #22 converted to commands; added startup and shut down scripts…
almostengr Jul 20, 2024
328b3dc
closed #21 gets next request when necessary
almostengr Jul 20, 2024
aeced81
Updated route for adding options
almostengr Jul 20, 2024
6d9c03d
Added PHP version dependency; updated command names
almostengr Jul 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**FPP information (please complete the following information):**
- Device [e.g. Beaglebone Black, Raspberry Pi]
- Version [e.g. 6.x]

**Additional context**
Add any other context about the problem here.
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: composer
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 5
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 5
14 changes: 14 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
on:
release:
types: [published]

jobs:
update_package:
runs-on: ubuntu-latest
steps:
- name: Packagist Update
uses: mnavarrocarter/packagist-update@v1.0.0
with:
username: almostengr
api_token: ${{ secrets.PACKAGIST_TOKEN }}
package_name: almostengr/show-pulse-fpp
40 changes: 40 additions & 0 deletions .github/workflows/run-php-unit-tests.yml.disabled
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Run PHPUnit Tests

on:
pull_request:
branches: [ "main" ]

permissions:
contents: read

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Validate composer.json and composer.lock
run: composer validate --strict

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-

- name: Install dependencies
run: composer install --prefer-dist --no-progress

# Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit"
# Docs: https://getcomposer.org/doc/articles/scripts.md

# - name: Run test suite
# run: composer run-script test

- name: Run PHPUnit tests
run: vendor/bin/phpunit --colors=never
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.phpunit.cache

/vendor/
.swp
46 changes: 44 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,44 @@
# light-show-guard-plugin
FPP Plugin for Light Show Guard
# Show Pulse Plugin for Falcon Pi Player

Show Pulse plugin allows you to see and remotely controller what happens with your light show. This
plugin is designed to work with Falcon Pi Player.


## Install Plugin

There are two ways to install the plugin. Using FPP user interface or using PHP's Composer.

### Using FPP

To install the plugin to your Falcon Pi Player, go to the Plugins section of the FPP. Then copy and
paste the URL below to install the plugin.

```sh
https://raw.githubusercontent.com/almostengr/show-pulse-fpp/main/pluginInfo.json
```

### Using Composer

Open a terminal or command prompt window, and go to the plugin directory or other directory of your chosing. Then enter the command

```sh
composer require almostengr/show-pulse-fpp
```

## Setup

See the [User Guide](https://lightshowpulse.com/pages/user-guide/fpp-plugin-quick-start) for how
to configure the plugin.


## Version Numbering

The version number for this plugin is in the following format. Using the example of

```txt
5.2024.07.26
```

"5" represents the major Falcon Pi Player version number that the plugin is designed for

"2024.07.26" represents the date, in YYYY-MM-DD format, that the release was created
41 changes: 41 additions & 0 deletions ShowPulseDaemon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace App;

use App\Commands\JukeboxSelectionInsertNextCommandHandler;
use App\Commands\PostStatusToWebsiteCommandHandler;
use App\Commands\ShowPulseConstant;
use Exception;

require_once "commands/InsertNextJukeboxSelectionCommandHandler.php";
require_once "commands/PostStatusToWebsiteCommandHandler.php";

$postStatusCommand = new PostStatusToWebsiteCommandHandler();
$nextSelectionCommand = new JukeboxSelectionInsertNextCommandHandler();

$failureCount = 0;
$delaySeconds = 2;

do {
try {
$postStatusCommand->execute();
$nextSelectionCommand->execute();

sleep(ShowPulseConstant::SLEEP_SHORT_VALUE);

$failureCount = 0;
} catch (Exception $e) {
if ($failureCount < ShowPulseConstant::MAX_FAILURES_ALLOWED) {
$message = $e->getMessage() . " (Attempt $failureCount)";
$postStatusCommand->logError($message);
$failureCount++;
}

$sleepTime = $failureCount * $delaySeconds;
sleep($sleepTime);
}

$daemonFileExists = file_exists(ShowPulseConstant::DAEMON_FILE);
} while ($daemonFileExists);

$postStatusCommand->logError("Daemon stopped.");
16 changes: 16 additions & 0 deletions about.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div style="margin:0 auto;"> <br />
<fieldset style="padding: 10px; border: 2px solid #000;">
<legend>Show Pulse Plugin</legend>
<div style="overflow: hidden; padding: 10px;">
<div id='credits'>
<b>Show Pulse Plugin Developed By:</b><br />
<br />
Kenny Robinson (almostengr)<br />
<br />
<a href='https://github.com/almostengr/show-pulse-fpp'>Git Repository</a><br>
<a href='https://github.com/almostengr/show-pulse-fpp/issues'>Bug Reporter</a><br>
<br />
</div>
</div>
</fieldset>
</div>
153 changes: 153 additions & 0 deletions commands/BaseCommandHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?php

namespace App\Commands;

$commonFile = $testing ? __DIR__ . "/tests/OptFppWwwCommonMock.php" : "/opt/fpp/www/common.php";
require_once $commonFile;

interface ShowPulseCommandHandlerInterface
{
protected function execute();
}

abstract class BaseCommandHandler
{
private $token;
private $showUuid;
private $websiteApiUrl;

protected function fppHttpRequest($route, $method = "GET", $data = null)
{
$headers = array();

array_push($headers, "Authorization: Bearer $this->token");

$url = "https://127.0.0.1/api/";
return $this->httpRequest($url, $route, $method, $data);
}

protected function httpRequest($url, $route, $method = "GET", $data = null)
{
$headers = array();


array_push($headers, "Content-Type: application/json");
array_push($headers, "Accept: application/json");

$url = $url . $route;

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$method = strtoupper($method);
if ($method === "POST" || $method === "PUT") {
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);

if ($response === false) {
return $this->logError("cURL error: " . curl_error($ch));
}

curl_close($ch);

if ($response === null) {
return $this->logError("Bad response returned.");
}

return json_decode($response, true);
}

protected function getShowUuid()
{
return $this->showUuid;
}

public function logError($message)
{
$currentDateTime = date('Y-m-d h:i:s A');
error_log("$currentDateTime: $message");
return false;
}

protected function isNullOrEmpty($value)
{
return is_null($value) || empty($value);
}

protected function isNotNullOrEmpty($value)
{
return !$this->isNullOrEmpty($value);
}

protected function loadConfiguration(): bool
{
$configFile = GetDirSetting("uploads") . "/showpulse.json";
$contents = file_get_contents($configFile);

if ($contents === false) {
return $this->logError("Configuration file not found or unable to be loaded. Download configuration file contents from the Light Show Pulse website. Then restart FPPD.");
}

$json = json_decode($contents, false);

$this->showUuid = $json->show_id;
$this->token = $json->token;
$this->websiteApiUrl = $json->host;
return true;
}

protected function getStatusFromFpp()
{
$fppStatus = $this->httpRequest(true, "fppd/status");

if ($this->isNullOrEmpty($fppStatus)) {
return $this->logError("Unable to get latest status from FPP.");
}

return $fppStatus;
}

protected function postStatusToWebsite($statusDto)
{
$response = $this->httpRequest(
false,
"show-statuses/add/" . $this->getShowUuid(),
"POST",
$statusDto
);

if ($response->failed) {
return $this->logError("Unable to update show status. " . $response->message);
}

return $response;
}
}

final class ShowPulseConstant
{
public const FPP_STATUS_IDLE = 0;
public const GRACEFUL_RESTART = "GRACEFUL RESTART";
public const GRACEFUL_SHUTDOWN = "GRACEFUL SHUTDOWN";
public const GRACEFUL_STOP = "GRACEFUL STOP";
public const HIGH_PRIORITY = 10;
public const IMMEDIATE_RESTART = "IMMEDIATE RESTART";
public const IMMEDIATE_SHUTDOWN = "IMMEDIATE SHUTDOWN";
public const IMMEDIATE_STOP = "IMMEDIATE STOP";
public const MAX_FAILURES_ALLOWED = 5;
public const SLEEP_SHORT_VALUE = 5;
public const DAEMON_FILE = "/home/fpp/media/plugins/show-pulse-fpp/daemon.run";
}

final class ShowPulseApiResponseDto
{
public $success;
public $failed;
public $message;
public $data;
}
Loading