diff --git a/ShellyPlug/ShellyPlug.php b/ShellyPlug/ShellyPlug.php new file mode 100644 index 0000000000..ad2f0fe33b --- /dev/null +++ b/ShellyPlug/ShellyPlug.php @@ -0,0 +1,175 @@ + "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( + $this->url("Shelly.GetStatus") + ); + echo $test->status; + } + + public function livestats() + { + $status = 'inactive'; + $res = parent::execute($this->url('Shelly.GetStatus')); + $details = json_decode($res->getBody()); + $res = parent::execute($this->url('Switch.GetStatus?id=0')); + $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); + } + + public function url($endpoint) + { + $api_url = parent::normaliseurl($this->config->url)."rpc/".$endpoint; + return $api_url; + } +} diff --git a/ShellyPlug/app.json b/ShellyPlug/app.json new file mode 100644 index 0000000000..80ed9017a4 --- /dev/null +++ b/ShellyPlug/app.json @@ -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" +} \ No newline at end of file diff --git a/ShellyPlug/config.blade.php b/ShellyPlug/config.blade.php new file mode 100644 index 0000000000..c058640fa0 --- /dev/null +++ b/ShellyPlug/config.blade.php @@ -0,0 +1,15 @@ +

{{ __('app.apps.config') }} ({{ __('app.optional') }}) @include('items.enable')

+
+
+ + {!! Form::text('config[override_url]', null, array('placeholder' => __('app.apps.override'), 'id' => 'override_url', 'class' => 'form-control')) !!} +
+
+ + {!! Form::select('config[availablestats][]', App\SupportedApps\ShellyPlug\ShellyPlug::getAvailableStats(), isset($item) ? $item->getConfig()->availablestats ?? null : null, ['multiple' => 'multiple']) !!} +
+
+ +
+
+ diff --git a/ShellyPlug/livestats.blade.php b/ShellyPlug/livestats.blade.php new file mode 100644 index 0000000000..795b9403ee --- /dev/null +++ b/ShellyPlug/livestats.blade.php @@ -0,0 +1,10 @@ + diff --git a/ShellyPlug/shellyplug.png b/ShellyPlug/shellyplug.png new file mode 100644 index 0000000000..41e44cbbfe Binary files /dev/null and b/ShellyPlug/shellyplug.png differ