Skip to content

Commit

Permalink
implement enhanced app for shelly plugs (#661)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bl4d3s authored Dec 2, 2023
1 parent ca4f54b commit 60d39c6
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 0 deletions.
175 changes: 175 additions & 0 deletions ShellyPlug/ShellyPlug.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<?php namespace App\SupportedApps\ShellyPlug;

class ShellyPlug extends \App\SupportedApps implements \App\EnhancedApps {

Check failure on line 3 in ShellyPlug/ShellyPlug.php

View workflow job for this annotation

GitHub Actions / Lint Code Base

Class App\SupportedApps\ShellyPlug\ShellyPlug extends unknown class App\SupportedApps.

Check failure on line 3 in ShellyPlug/ShellyPlug.php

View workflow job for this annotation

GitHub Actions / Lint Code Base

Class App\SupportedApps\ShellyPlug\ShellyPlug implements unknown interface App�nhancedApps.

public $config;

function __construct() {
}

public static function getAvailableStats()
{
return [
"cloud" => "Cloud",
"mqtt" => "MQTT",
"ws" => "Websocket",
"sysUptime" => "Uptime",
"state" => "State",
"power" => "Watts",
"tempC" => "Temperature in °C",
"tempF" => "Temperature in °F",
];
}

private static function toTime($timestamp)
{
$hours = floor($timestamp / 3600);
$minutes = floor($timestamp % 3600 / 60);
$seconds = $timestamp % 60;

$hourDuration = sprintf('%02dh', $hours);
$minDuration = sprintf('%02dm', $minutes);
$secDuration = sprintf('%02ds', $seconds);
$HourMinSec = $hourDuration.$minDuration.$secDuration;

if($hourDuration > 0){
$hourDuration = $hourDuration;
} else {
$hourDuration = '00h';
}

if($minDuration > 0){
$minDuration = $minDuration;
} else {
$minDuration = '00m';
}

if($secDuration > 0){
$secDuration = $secDuration;
} else {
$secDuration = '00s';
}

$HourMinSec = $hourDuration.$minDuration.$secDuration;

return $HourMinSec;
}

private static function formatValueUsingStat($stat, $value)
{
if (!isset($value)) {
return "N/A";
}

switch ($stat) {
case "cloud":
case "mqtt":
case "ws":
return (bool)$value ? "Connected" : "Disconnected";
case "sysUptime":
return self::toTime((int)$value);
case "state":
return (bool)$value ? "On" : "Off";
case "power":
return "{$value} W";
case "tempC":
return "{$value} °C";
case "tempF":
return "{$value} °F";
default:
return "{$value}";
}
}

public function test()
{
$test = parent::appTest(

Check failure on line 86 in ShellyPlug/ShellyPlug.php

View workflow job for this annotation

GitHub Actions / Lint Code Base

App\SupportedApps\ShellyPlug\ShellyPlug::test() calls parent::appTest() but App\SupportedApps\ShellyPlug\ShellyPlug does not extend any class.
$this->url("Shelly.GetStatus")
);
echo $test->status;
}

public function livestats()
{
$status = 'inactive';
$res = parent::execute($this->url('Shelly.GetStatus'));

Check failure on line 95 in ShellyPlug/ShellyPlug.php

View workflow job for this annotation

GitHub Actions / Lint Code Base

App\SupportedApps\ShellyPlug\ShellyPlug::livestats() calls parent::execute() but App\SupportedApps\ShellyPlug\ShellyPlug does not extend any class.
$details = json_decode($res->getBody());
$res = parent::execute($this->url('Switch.GetStatus?id=0'));

Check failure on line 97 in ShellyPlug/ShellyPlug.php

View workflow job for this annotation

GitHub Actions / Lint Code Base

App\SupportedApps\ShellyPlug\ShellyPlug::livestats() calls parent::execute() but App\SupportedApps\ShellyPlug\ShellyPlug does not extend any class.
$switch = json_decode($res->getBody());

$data = ["visiblestats" => []];
if ($details) {
foreach ($this->config->availablestats as $stat) {
if (!isset(self::getAvailableStats()[$stat])) {
continue;
}

$newstat = new \stdClass();

switch ($stat) {
case "cloud":
$newstat->title = self::getAvailableStats()[$stat];
$newstat->value = self::formatValueUsingStat(
$stat,
$details->cloud->connected
);
break;
case "mqtt":
$newstat->title = self::getAvailableStats()[$stat];
$newstat->value = self::formatValueUsingStat(
$stat,
$details->mqtt->connected
);
break;
case "ws":
$newstat->title = self::getAvailableStats()[$stat];
$newstat->value = self::formatValueUsingStat(
$stat,
$details->ws->connected
);
break;
case "sysUptime":
$newstat->title = self::getAvailableStats()[$stat];
$newstat->value = self::formatValueUsingStat(
$stat,
$details->sys->uptime
);
break;
case "state":
$newstat->value = self::formatValueUsingStat(
$stat,
$switch->output
);
break;
case "power":
$newstat->value = self::formatValueUsingStat(
$stat,
$switch->apower
);
break;
case "tempC":
$newstat->value = self::formatValueUsingStat(
$stat,
$switch->temperature->tC
);
break;
case "tempF":
$newstat->value = self::formatValueUsingStat(
$stat,
$switch->temperature->tF
);
break;
}
$data["visiblestats"][] = $newstat;
}
}

return parent::getLiveStats($status, $data);

Check failure on line 167 in ShellyPlug/ShellyPlug.php

View workflow job for this annotation

GitHub Actions / Lint Code Base

App\SupportedApps\ShellyPlug\ShellyPlug::livestats() calls parent::getLiveStats() but App\SupportedApps\ShellyPlug\ShellyPlug does not extend any class.
}

public function url($endpoint)
{
$api_url = parent::normaliseurl($this->config->url)."rpc/".$endpoint;

Check failure on line 172 in ShellyPlug/ShellyPlug.php

View workflow job for this annotation

GitHub Actions / Lint Code Base

App\SupportedApps\ShellyPlug\ShellyPlug::url() calls parent::normaliseurl() but App\SupportedApps\ShellyPlug\ShellyPlug does not extend any class.
return $api_url;
}
}
10 changes: 10 additions & 0 deletions ShellyPlug/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"appid": "304c38e1914566a45eb705ba7315a638d25b44ce",
"name": "Shelly Plug",
"website": "https://www.shelly.com/",
"license": "MIT License",
"description": "Shelly offers easy-to-use products for smart home enthusiasts and professionals. The wide product range delivers complete home automation experience and innovative technology at reasonable prices and with attention to the smallest details.\r\n\r\nThis application supports Shelly Plugs.",
"enhanced": true,
"tile_background": "dark",
"icon": "shellyplug.png"
}
15 changes: 15 additions & 0 deletions ShellyPlug/config.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<h2>{{ __('app.apps.config') }} ({{ __('app.optional') }}) @include('items.enable')</h2>
<div class="items">
<div class="input">
<label>{{ strtoupper(__('app.url')) }}</label>
{!! Form::text('config[override_url]', null, array('placeholder' => __('app.apps.override'), 'id' => 'override_url', 'class' => 'form-control')) !!}
</div>
<div class="input">
<label>Stats to show</label>
{!! Form::select('config[availablestats][]', App\SupportedApps\ShellyPlug\ShellyPlug::getAvailableStats(), isset($item) ? $item->getConfig()->availablestats ?? null : null, ['multiple' => 'multiple']) !!}
</div>
<div class="input">
<button style="margin-top: 32px;" class="btn test" id="test_config">Test</button>
</div>
</div>

10 changes: 10 additions & 0 deletions ShellyPlug/livestats.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<ul class="livestats">
@foreach ($visiblestats as $stat)
<li>
@if (isset($stat->title))
<span class="title">{!! $stat->title !!}</span>
@endif
<strong>{!! $stat->value !!}</strong>
</li>
@endforeach
</ul>
Binary file added ShellyPlug/shellyplug.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 60d39c6

Please sign in to comment.