diff --git a/.env b/.env index 01c8e8ec..a2ab2e48 100644 --- a/.env +++ b/.env @@ -4,6 +4,8 @@ APP_KEY=base64:Kx0bZ0S6BUK05v9vam8ty+7Zsigqlp/Wqf+cbLCyOEM= APP_DEBUG=true APP_URL=http://localhost +API_URL=http://core.redroundrobin.site:9999 + LOG_CHANNEL=stack BROADCAST_DRIVER=log diff --git a/.github/ISSUE_TEMPLATE/backend---bug-report.md b/.github/ISSUE_TEMPLATE/backend---bug-report.md new file mode 100644 index 00000000..4e56abf0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/backend---bug-report.md @@ -0,0 +1,14 @@ +--- +name: Backend - Bug report +about: Bug trovato che va corretto nel Backend +title: "[BACKEND] " +labels: bug +assignees: BroHPotato + +--- + +**Descrizione del bug** +Descrivi il problema + +**Modifica da fare** +Come va modificato diff --git a/.github/ISSUE_TEMPLATE/frontend---bug-report.md b/.github/ISSUE_TEMPLATE/frontend---bug-report.md new file mode 100644 index 00000000..9b15875e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/frontend---bug-report.md @@ -0,0 +1,17 @@ +--- +name: Frontend - Bug report +about: Bug trovato che va corretto nel Frontend +title: "[FRONTEND] " +labels: bug +assignees: aletomm, giovd8, Maxelweb + +--- + +**Descrizione del bug** +Descrivi il problema + +**Modifica da fare** +Come va modificato + +**Tipo di browser** +DESKTOP / MOBILE diff --git a/README.md b/README.md index 135ee73c..3359990c 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,21 @@ # Web application - ThiReMa -:fire: Versione componente: `v0.0.1-dev` +:fire: Versione componente: `v0.1.0-dev` -:pushpin: Main repo: [swe-thirema](https://github.com/Maxelweb/swe-thirema) +:pushpin: Main repo: [swe-thirema](https://github.com/RedRoundRobin/swe-thirema) --- +[](https://sonarcloud.io/dashboard?id=RedRoundRobin_swe-webapp) + + + + + +[](https://coveralls.io/github/RedRoundRobin/swe-webapp?branch=develop) + + ### Installazione e primo avvio 1. composer update diff --git a/__tests__/ChartManagement.test.js b/__tests__/ChartManagement.test.js index 82e1acdc..8b194b5b 100644 --- a/__tests__/ChartManagement.test.js +++ b/__tests__/ChartManagement.test.js @@ -5,11 +5,10 @@ import ChartManagement from "../resources/js/components/ChartManagement.vue"; describe("ChartManagement", () => { test("is a Vue instance", () => { - const user = {}; - const device = {}; - const sensor = { sensorId: 1 }; + const deviceId = 1; + const sensorId = 1; const chart = mount(ChartManagement, { - propsData: { user, device, sensor }, + propsData: { deviceId, sensorId }, }); expect(chart.isVueInstance()).toBeTruthy(); }); diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 04ddc058..10bb385a 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -45,6 +45,9 @@ protected function redirectTo() */ public function __construct() { + /*session()->flush(); + session_reset(); + Auth::logout();*/ $this->middleware('guest')->except('logout'); } @@ -59,7 +62,6 @@ public function authenticate(Request $request) if (Auth::attempt($credentials)) { // Authentication passed... return redirect(RouteServiceProvider::DASHBOARD); - ; } } public function showTfaForm() diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index 9f1e47df..620b59af 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -2,6 +2,9 @@ namespace App\Http\Controllers; +use App\Providers\DeviceServiceProvider; +use App\Providers\EntityServiceProvider; +use App\Providers\UserServiceProvider; use Illuminate\Support\Facades\Auth; class DashboardController extends Controller @@ -12,7 +15,26 @@ public function __construct() } public function index() { + $userProvider = new UserServiceProvider(); + $entityProvider = new EntityServiceProvider(); + $deviceProvider = new DeviceServiceProvider(); + $user = Auth::user(); - return view('dashboard.index', compact('user')); + $entities = $entityProvider->findAll();//enti presenti + $users = $userProvider->findAll();//utenti registrati + $devices = $deviceProvider->findAll();//dispositivi registrati + + $devicesEntity = $deviceProvider->findAllFromEntity($entityProvider->findFromUser($user->getAuthIdentifier())); + $usersEntity = $userProvider->findAllFromEntity($entityProvider->findFromUser($user->getAuthIdentifier())); + + $usersActive = array_filter($users, function ($u) { + return !$u->deleted; + }); + $usersActiveEntity = array_filter($usersEntity, function ($u) { + return !$u->deleted; + }); + return view('dashboard.index', compact([ + 'user', 'users', 'entities', 'devices', 'devicesEntity', 'usersEntity', 'usersActive', 'usersActiveEntity' + ])); } } diff --git a/app/Http/Controllers/DeviceController.php b/app/Http/Controllers/DeviceController.php index a2aec453..15a743ad 100644 --- a/app/Http/Controllers/DeviceController.php +++ b/app/Http/Controllers/DeviceController.php @@ -22,6 +22,18 @@ public function __construct() $this->provider = new DeviceServiceProvider(); } + public function create() + { + $entities = $this->provider->findAll(); + return view('devices.create', compact(['entities'])); + } + + public function edit($device) + { + $device = $this->provider->retrieveById($device); + return view('devices.edit', compact('user')); + } + /** * Display a listing of the resource. * @@ -29,7 +41,8 @@ public function __construct() */ public function index() { - $devices = $this->provider->findAll(); + //$devices = $this->provider->findAll(); + ///FAKER $user = new Device(); $arr = array_combine( array('deviceId', 'name', 'frequency', 'gatewayId'), @@ -37,6 +50,7 @@ public function index() ); $user->fill($arr); $devices[] = $user; + //TODO remove return view('devices.index', compact('devices')); } @@ -48,7 +62,16 @@ public function index() */ public function show($device) { - $device = $this->provider->retrieveById($device); + //$device = $this->provider->find($device); + ///FAKER + $user = new Device(); + $arr = array_combine( + array('deviceId', 'name', 'frequency', 'gatewayId'), + array("1", "dev1", 123, 1) + ); + $user->fill($arr); + $device = $user; + //TODO remove return view('devices.show', compact('device')); } } diff --git a/app/Http/Controllers/SensorController.php b/app/Http/Controllers/SensorController.php index 1d9384b5..3bd56ac4 100644 --- a/app/Http/Controllers/SensorController.php +++ b/app/Http/Controllers/SensorController.php @@ -26,10 +26,10 @@ public function __construct() * * @return Factory|View */ - public function index() + public function index($device) { - $sensors = $this->provider->findAll(); - return view('sensors.index', compact('sensors')); + $sensors = $this->provider->findAllFromDevice($device); + return view('sensors.index', compact(['sensors', 'device'])); } /** @@ -38,9 +38,14 @@ public function index() * @param $sensor * @return Factory|View */ - public function show($sensor) + public function show($device, $sensor) { - $sensor = $this->provider->retrieveById($sensor); - return view('sensors.show', compact('sensor')); + $sensor = $this->provider->find($device, $sensor); + return view('sensors.show', compact(['sensor', 'device'])); + } + + public function fetch($device, $sensor) + { + return $this->provider->fetch($device, $sensor); } } diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index f48b873a..ddf0d8ba 100644 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -51,17 +51,13 @@ public function update() if (key_exists('tfa', $data)) { $data['tfa'] = boolval($data['tfa']); - } else { - $data['tfa'] = false; } if ($data['telegramName'] != $user->getTelegramName() || is_null($user->getChatId())) { $data['tfa'] = false; } - - $user->fill($data); + $data = array_diff_assoc($data, $user->getAttributes()); $service = new UserServiceProvider(); - $service->update('/user/' . $user->getAuthIdentifier(), $user); - Auth::login($user); + $service->update($user->getAuthIdentifier(), json_encode($data)); return redirect('/settings/edit'); } } diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 07202080..acf9ed6a 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -2,14 +2,27 @@ namespace App\Http\Controllers; -use App\Models\User; +use App\Models\Entity; +use App\Providers\EntityServiceProvider; use App\Providers\UserServiceProvider; -use GuzzleHttp\Client; use Illuminate\Contracts\Support\Renderable; +use Illuminate\Contracts\View\Factory; +use Illuminate\Http\RedirectResponse; +use Illuminate\Routing\Redirector; +use Illuminate\Support\Facades\Auth; +use Illuminate\View\View; +/** + * Class UserController + * @package App\Http\Controllers + */ class UserController extends Controller { + /** + * @var UserServiceProvider + */ private $provider; + /** * Create a new controller instance. * @@ -44,66 +57,107 @@ public function show($user) return view('users.show', compact('user')); } + /** + * @return Factory|View + */ public function create() { - return view('users.create'); + $entityProvider = new EntityServiceProvider(); + $entities = $entityProvider->findAll(); + return view('users.create', compact(['entities'])); } + /** + * @param $user + * @return Factory|View + */ public function edit($user) { $user = $this->provider->retrieveById($user); return view('users.edit', compact('user')); } + /** + * + */ public function store() { $data = request()->validate([ - - ]); - $request = new Client([ - 'base_uri' => 'localhost:9999', - 'headers' => [ - 'Content-Type' => 'application/json', - 'Authorization' => 'Bearer ' . session()->get('token') - ] - ]); - $user = new User(); - $user->fill($data); - $request->post('/users/create', [ - 'body' => $user + 'name' => 'required|string', + 'surname' => 'required|string', + 'email' => 'required|email', + 'entityId' => 'nullable|numeric|required_if:' . Auth::user()->getRole() . ',==,Admin', + 'type' => 'nullable|numeric|required_if:' . Auth::user()->getRole() . ',==,Admin', + 'password_check' => 'required|in:' . Auth::user()->getAuthPassword(), ]); + unset($data['password_check']);//todo to remove + $data['password'] = "password"; + if (!key_exists('entityId', $data)) { + $data['entityId'] = 1; //(new EntityServiceProvider())->findFromUser(Auth::id())->entityId; + } + if (!key_exists('type', $data)) { + $data['type'] = 0; + } + $this->provider->store(json_encode($data)); } + /** + * @param $user + * @return RedirectResponse|Redirector + */ public function update($user) { - $data = request()->validate([ - - ]); $user = $this->provider->retrieveById($user); - $user->fill($data); - $request = new Client([ - 'base_uri' => 'localhost:9999', - 'headers' => [ - 'Content-Type' => 'application/json', - 'Authorization' => 'Bearer ' . session()->get('token') - ] + $data = request()->validate([ + 'name' => 'required|string', + 'surname' => 'required|string', + 'type' => 'in:1,2,3|numeric|required_if:' . Auth::user()->getRole() . '==, "isAdmin"', + 'email' => 'required|email', + 'telegramName' => 'nullable|string|required_if:tfa,==,true', + 'telegramChat' => 'nullable|string|required_if:tfa,==,true', + 'tfa' => 'nullable|in:true', + 'deleted' => 'nullable|in:true', + 'password' => 'nullable|min:6', + 'password_check' => 'required|in:' . Auth::user()->getAuthPassword(), ]); + unset($data['password_check']);//todo to remove + $data = array_diff_assoc($data, $user->getAttributes()); - $request->put('/user/' . $user->getAuthIdentifier() . '/update', [ - 'body' => $user - ]); + if (key_exists('deleted', $data)) { + $data['deleted'] = boolval($data['deleted']); + } + + if (key_exists('tfa', $data)) { + $data['tfa'] = boolval($data['tfa']); + } + + if (key_exists('telegramName', $data)) { + if ($data['telegramName'] != $user->getTelegramName() || is_null($user->getChatId())) { + $data['tfa'] = false; + } + } + $this->provider->update($user->getAuthIdentifier(), json_encode($data, JSON_FORCE_OBJECT)); + return redirect(route('users.index')); } + /** + * @param $userId + * @return RedirectResponse|Redirector + */ + public function destroy($userId) + { + $this->provider->destroy($userId); + return redirect(route('users.index')); + } - public function delete($user) + /** + * @param $userId + */ + public function restore($userId) { - $request = new Client([ - 'base_uri' => 'localhost:9999', - 'headers' => [ - 'Content-Type' => 'application/json', - 'Authorization' => 'Bearer ' . session()->get('token') - ] - ]); - $request->delete('/user/' . $user); + dd($userId);//todo to remove + $user = $this->provider->retrieveById($userId); + $user->setDeleted(false); + $this->provider->update($user->getAuthIdentifier(), $user); } } diff --git a/app/Models/Device.php b/app/Models/Device.php index 711ab481..bf8a11a1 100644 --- a/app/Models/Device.php +++ b/app/Models/Device.php @@ -2,9 +2,23 @@ namespace App\Models; +use App\Providers\EntityServiceProvider; +use App\Providers\SensorServiceProvider; use Illuminate\Database\Eloquent\Model; class Device extends Model { protected $fillable = ['deviceId', 'name', 'frequency', 'gatewayId']; + + public function getSensors() + { + $provider = new SensorServiceProvider(); + return $provider->findAllFromDevice($this->deviceId); + } + + public function getEntity() + { + $provider = new EntityServiceProvider(); + return $provider->findFromDevice($this->deviceId); + } } diff --git a/app/Models/Entity.php b/app/Models/Entity.php index 98f7eb74..32287686 100644 --- a/app/Models/Entity.php +++ b/app/Models/Entity.php @@ -7,4 +7,9 @@ class Entity extends Model { protected $fillable = ['entityId', 'name', 'location', 'deleted']; + + public function getName() + { + return $this->name; + } } diff --git a/app/Models/User.php b/app/Models/User.php index 73a1033d..b32d70bc 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -48,4 +48,9 @@ public function getRole() { return $this->role[$this->type]; } + + public function setDeleted(bool $b) + { + $this->deleted = $b; + } } diff --git a/app/Providers/DeviceServiceProvider.php b/app/Providers/DeviceServiceProvider.php index 60f0bc86..31b2b23b 100644 --- a/app/Providers/DeviceServiceProvider.php +++ b/app/Providers/DeviceServiceProvider.php @@ -5,20 +5,34 @@ use App\Models\Device; use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; +use Illuminate\Http\RedirectResponse; +use Illuminate\Routing\Redirector; use Illuminate\Support\ServiceProvider; +use function config; + +/** + * Class DeviceServiceProvider + * @package App\Providers + */ class DeviceServiceProvider extends ServiceProvider { //si occupa di prendere i device dal database + /** + * @var Client + */ private $request; + /** + * DeviceServiceProvider constructor. + */ public function __construct() { parent::__construct(app()); $this->request = new Client([ - 'base_uri' => 'localhost:9999', + 'base_uri' => config('app.api') . '/devices', 'headers' => [ - 'Content-Type' => 'application/json' , + 'Content-Type' => 'application/json' ] ]); } @@ -27,10 +41,10 @@ public function __construct() * @param mixed $identifier * @return Device */ - public function retrieveById($identifier) + public function find($identifier) { try { - $response = json_decode($this->request->get('device/' . $identifier, [ + $response = json_decode($this->request->get($identifier, [ 'headers' => [ 'Authorization' => 'Bearer ' . session()->get('token') ] @@ -40,7 +54,7 @@ public function retrieveById($identifier) return $device; } catch (RequestException $e) { $this->isExpired($e); - return null; + abort($e->getCode(), $e->getResponse()->getReasonPhrase()); } } @@ -50,11 +64,11 @@ public function retrieveById($identifier) public function findAll() { try { - $response = json_decode($this->request->get('devices', [ + $response = json_decode($this->request->get('', [ 'headers' => [ 'Authorization' => 'Bearer ' . session()->get('token') - ] - ])->getBody()); + ] + ])->getBody()); $devices = []; foreach ($response as $d) { $device = new Device(); @@ -68,6 +82,10 @@ public function findAll() } } + /** + * @param RequestException $e + * @return RedirectResponse|Redirector + */ private function isExpired(RequestException $e) { if ($e->getCode() == 419/*fai il controllo del token*/) { @@ -76,4 +94,30 @@ private function isExpired(RequestException $e) return redirect('login'); } } + + /** + * @param $entity + * @return array + */ + public function findAllFromEntity($entity) + { + try { + $response = json_decode($this->request->get('', [ + 'headers' => [ + 'Authorization' => 'Bearer ' . session()->get('token') + ], + 'query' => 'entityId=' . $entity + ])->getBody()); + $devices = []; + foreach ($response as $d) { + $device = new Device(); + $device->fill((array)$d); + $devices[] = $device; + } + return $devices; + } catch (RequestException $e) { + $this->isExpired($e); + abort($e->getCode(), $e->getResponse()->getReasonPhrase()); + } + } } diff --git a/app/Providers/EntityServiceProvider.php b/app/Providers/EntityServiceProvider.php index 3b8dcf0f..7b2b304c 100644 --- a/app/Providers/EntityServiceProvider.php +++ b/app/Providers/EntityServiceProvider.php @@ -5,20 +5,34 @@ use App\Models\Entity; use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; +use Illuminate\Http\RedirectResponse; +use Illuminate\Routing\Redirector; use Illuminate\Support\ServiceProvider; +use function config; + +/** + * Class EntityServiceProvider + * @package App\Providers + */ class EntityServiceProvider extends ServiceProvider { //si occupa di prendere i device dal database + /** + * @var Client + */ private $request; + /** + * EntityServiceProvider constructor. + */ public function __construct() { parent::__construct(app()); $this->request = new Client([ - 'base_uri' => 'localhost:9999', + 'base_uri' => config('app.api') . '/entities', 'headers' => [ - 'Content-Type' => 'application/json' , + 'Content-Type' => 'application/json' ] ]); } @@ -30,7 +44,7 @@ public function __construct() public function retrieveById($identifier) { try { - $response = json_decode($this->request->get('enity/' . $identifier, [ + $response = json_decode($this->request->get($identifier, [ 'headers' => [ 'Authorization' => 'Bearer ' . session()->get('token') ] @@ -39,18 +53,32 @@ public function retrieveById($identifier) $entity->fill((array)$response); return $entity; } catch (RequestException $e) { + $this->isExpired($e); abort($e->getCode(), $e->getResponse()->getReasonPhrase()); return null; } } + /** + * @param RequestException $e + * @return RedirectResponse|Redirector + */ + private function isExpired(RequestException $e) + { + if ($e->getCode() == 419/*fai il controllo del token*/) { + session()->invalidate(); + session()->flush(); + return redirect('login'); + } + } + /** * @return array|null */ public function findAll() { try { - $response = json_decode($this->request->get('entities', [ + $response = json_decode($this->request->get('', [ 'headers' => [ 'Authorization' => 'Bearer ' . session()->get('token') ] @@ -63,6 +91,53 @@ public function findAll() } return $entities; } catch (RequestException $e) { + $this->isExpired($e); + abort($e->getCode(), $e->getResponse()->getReasonPhrase()); + return null; + } + } + + /** + * @param $deviceId + * @return Entity|null + */ + public function findFromDevice($deviceId) + { + try { + $response = json_decode($this->request->get('entities', [ + 'headers' => [ + 'Authorization' => 'Bearer ' . session()->get('token') + ], + 'query' => 'deviceId=' . $deviceId + ])->getBody()); + $entity = new Entity(); + $entity->fill((array)$response); + return $entity; + } catch (RequestException $e) { + $this->isExpired($e); + abort($e->getCode(), $e->getResponse()->getReasonPhrase()); + return null; + } + } + + /** + * @param $userId + * @return Entity|null + */ + public function findFromUser($userId) + { + try { + $response = json_decode($this->request->get('entities', [ + 'headers' => [ + 'Authorization' => 'Bearer ' . session()->get('token') + ], + 'query' => 'userId=' . $userId + ])->getBody()); + $entity = new Entity(); + $entity->fill((array)$response); + return $entity; + } catch (RequestException $e) { + $this->isExpired($e); abort($e->getCode(), $e->getResponse()->getReasonPhrase()); return null; } diff --git a/app/Providers/GatewayServiceProvider.php b/app/Providers/GatewayServiceProvider.php index c66f0c51..1bdacf51 100644 --- a/app/Providers/GatewayServiceProvider.php +++ b/app/Providers/GatewayServiceProvider.php @@ -7,18 +7,30 @@ use GuzzleHttp\Exception\RequestException; use Illuminate\Support\ServiceProvider; +use function config; + +/** + * Class GatewayServiceProvider + * @package App\Providers + */ class GatewayServiceProvider extends ServiceProvider { //si occupa di prendere i device dal database + /** + * @var Client + */ private $request; + /** + * GatewayServiceProvider constructor. + */ public function __construct() { parent::__construct(app()); $this->request = new Client([ - 'base_uri' => 'localhost:9999', + 'base_uri' => config('app.api') . '/gateways', 'headers' => [ - 'Content-Type' => 'application/json' , + 'Content-Type' => 'application/json', ] ]); } @@ -30,7 +42,7 @@ public function __construct() public function retrieveById($identifier) { try { - $response = json_decode($this->request->get('gateways/' . $identifier, [ + $response = json_decode($this->request->get($identifier, [ 'headers' => [ 'Authorization' => 'Bearer ' . session()->get('token') ] @@ -50,7 +62,7 @@ public function retrieveById($identifier) public function findAll() { try { - $response = json_decode($this->request->get('gateways', [ + $response = json_decode($this->request->get('', [ 'headers' => [ 'Authorization' => 'Bearer ' . session()->get('token') ] diff --git a/app/Providers/SensorServiceProvider.php b/app/Providers/SensorServiceProvider.php index 5a627698..44083f69 100644 --- a/app/Providers/SensorServiceProvider.php +++ b/app/Providers/SensorServiceProvider.php @@ -5,20 +5,32 @@ use App\Models\Sensor; use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; +use Illuminate\Http\RedirectResponse; +use Illuminate\Routing\Redirector; use Illuminate\Support\ServiceProvider; +/** + * Class SensorServiceProvider + * @package App\Providers + */ class SensorServiceProvider extends ServiceProvider { //si occupa di prendere i device dal database + /** + * @var Client + */ private $request; + /** + * SensorServiceProvider constructor. + */ public function __construct() { parent::__construct(app()); $this->request = new Client([ - 'base_uri' => 'localhost:9999', + 'base_uri' => config('app.api') . '/devices', 'headers' => [ - 'Content-Type' => 'application/json' , + 'Content-Type' => 'application/json' ] ]); } @@ -27,20 +39,36 @@ public function __construct() * @param mixed $identifier * @return Sensor */ - public function retrieveById($identifier) + public function find($deviceId, $sensorId) { try { - $response = json_decode($this->request->get('sensor/' . $identifier, [ + $response = json_decode($this->request->get($deviceId . '/sensor/' . $sensorId, [ 'headers' => [ 'Authorization' => 'Bearer ' . session()->get('token') - ] + ], ])->getBody()); $sensor = new Sensor(); $sensor->fill((array)$response); return $sensor; } catch (RequestException $e) { - abort($e->getCode(), $e->getResponse()->getReasonPhrase()); - return null; + $this->isExpired($e); + //abort($e->getCode(), $e->getResponse()->getReasonPhrase()); + $s = new Sensor(); + $s->fill(array_combine(['sensorId', 'type', 'deviceSensorId', 'deviceId'], [1, 'boh', 1, 1])); + return $s;//null; + } + } + + /** + * @param RequestException $e + * @return RedirectResponse|Redirector + */ + private function isExpired(RequestException $e) + { + if ($e->getCode() == 419/*fai il controllo del token*/) { + session()->invalidate(); + session()->flush(); + return redirect('login'); } } @@ -63,8 +91,58 @@ public function findAll() } return $sensors; } catch (RequestException $e) { + $this->isExpired($e); abort($e->getCode(), $e->getResponse()->getReasonPhrase()); return null; } } + + /** + * @param $deviceId + * @return array + */ + public function findAllFromDevice($deviceId) + { + try { + $response = json_decode($this->request->get($deviceId . '/sensors', [ + 'headers' => [ + 'Authorization' => 'Bearer ' . session()->get('token') + ] + ])->getBody()); + $sensors = []; + foreach ($response as $d) { + $sensor = new Sensor(); + $sensor->fill((array)$d); + $sensors[] = $sensor; + } + return $sensors; + } catch (RequestException $e) { + $this->isExpired($e); + //abort($e->getCode(), $e->getResponse()->getReasonPhrase()); + $s1 = new Sensor(); + $s2 = new Sensor(); + $s1->fill(array_combine(['sensorId', 'type', 'deviceSensorId', 'deviceId'], [1, 'boh', 1, 1])); + $s2->fill(array_combine(['sensorId', 'type', 'deviceSensorId', 'deviceId'], [2, 'buh', 2, 1])); + return [$s1, $s2];//null; + } + } + + /** + * @param $device + * @param $sensorId + * @return mixed + */ + public function fetch($device, $sensorId) + { + try { + return json_decode($this->request->get('sensor', [ + 'headers' => [ + 'Authorization' => 'Bearer ' . session()->get('token') + ] + ])->getBody()); + } catch (RequestException $e) { + $this->isExpired($e); + return NAN; + } + } } diff --git a/app/Providers/UserServiceProvider.php b/app/Providers/UserServiceProvider.php index 9b020803..10597fcf 100644 --- a/app/Providers/UserServiceProvider.php +++ b/app/Providers/UserServiceProvider.php @@ -9,17 +9,31 @@ use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\UserProvider; use Illuminate\Http\RedirectResponse; +use Illuminate\Routing\Redirector; +use Illuminate\Support\Facades\Auth; +use function config; + +/** + * Class UserServiceProvider + * @package App\Providers + */ class UserServiceProvider extends ServiceProvider implements UserProvider { //si occupa di prendere lo user dal database + /** + * @var Client + */ private $request; + /** + * UserServiceProvider constructor. + */ public function __construct() { parent::__construct(app()); $this->request = new Client([ - 'base_uri' => 'localhost:9999', + 'base_uri' => config('app.api'), 'headers' => [ 'Content-Type' => 'application/json' ] @@ -33,7 +47,7 @@ public function __construct() public function retrieveById($identifier) { try { - $response = json_decode($this->request->get('user/' . $identifier, [ + $response = json_decode($this->request->get('users/' . $identifier, [ 'headers' => [ 'Authorization' => 'Bearer ' . session()->get('token') ] @@ -47,6 +61,19 @@ public function retrieveById($identifier) } } + /** + * @param RequestException $e + * @return RedirectResponse|Redirector + */ + private function isExpired(RequestException $e) + { + if ($e->getCode() == 419/*fai il controllo del token*/) { + session()->invalidate(); + session()->flush(); + return redirect('login'); + } + } + /** * @param mixed $identifier * @param string $token @@ -58,8 +85,8 @@ public function retrieveByToken($identifier, $token) } /** public function __construct() - { - } + * { + * } * @param Authenticatable $user * @param string $token */ @@ -86,36 +113,10 @@ public function retrieveByCredentials(array $credentials) } /** - * @param Authenticatable $user - * @param array $credentials - * @return bool + * @param Client $request + * @param $credentials + * @return User */ - public function validateCredentials($user, array $credentials) - { - return true; - } - - public function findAll() - { - try { - $response = json_decode($this->request->get('users', [ - 'headers' => [ - 'Authorization' => 'Bearer ' . session()->get('token') - ] - ])->getBody()); - $users = []; - foreach ($response as $u) { - $user = new User(); - $user->fill((array)$u); - $users[] = $user; - } - return $users; - } catch (RequestException $e) { - $this->isExpired($e); - abort($e->getCode(), $e->getResponse()->getReasonPhrase()); - } - } - private function retriveByCode(Client $request, $credentials) { $response = json_decode($request->post('auth/tfa', [ @@ -133,6 +134,11 @@ private function retriveByCode(Client $request, $credentials) return $user; } + /** + * @param Client $request + * @param $credentials + * @return User|RedirectResponse|Redirector + */ private function retriveByCred(Client $request, $credentials) { $response = json_decode($request->post('auth', [ @@ -153,14 +159,99 @@ private function retriveByCred(Client $request, $credentials) } } - public function update(string $where, string $body) + /** + * @param Authenticatable $user + * @param array $credentials + * @return bool + */ + public function validateCredentials($user, array $credentials) + { + return true; + } + + /** + * @return array + */ + public function findAll() { try { - $this->request->put($where . '/update', [ + $response = json_decode($this->request->get('users', [ + 'headers' => [ + 'Authorization' => 'Bearer ' . session()->get('token') + ] + ])->getBody()); + $users = []; + foreach ($response as $u) { + $user = new User(); + $user->fill((array)$u); + $users[] = $user; + } + return $users; + } catch (RequestException $e) { + $this->isExpired($e); + abort($e->getCode(), $e->getResponse()->getReasonPhrase()); + } + } + + /** + * @param $entityId + * @return array + */ + public function findAllFromEntity($entityId) + { + try { + $response = json_decode($this->request->get('users', [ + 'headers' => [ + 'Authorization' => 'Bearer ' . session()->get('token') + ], + 'query' => 'entityId=' . $entityId + ])->getBody()); + $users = []; + foreach ($response as $u) { + $user = new User(); + $user->fill((array)$u); + $users[] = $user; + } + return $users; + } catch (RequestException $e) { + $this->isExpired($e); + abort($e->getCode(), $e->getResponse()->getReasonPhrase()); + } + } + + /** + * @param string $who + * @param string $body + */ + public function update(string $who, string $body) + { + try { + $response = json_decode($this->request->put('/users/' . $who, [ 'headers' => [ 'Authorization' => 'Bearer ' . session()->get('token') ], 'body' => $body + ])->getBody()); + if (property_exists($response, 'token')) { + session(['token' => $response->token]); + Auth::user()->token = $response->token; + } + } catch (RequestException $e) { + $this->isExpired($e); + abort($e->getCode(), $e->getResponse()->getReasonPhrase()); + } + } + + /** + * @param string $who + */ + public function destroy(string $who) + { + try { + $this->request->delete('/users/' . $who, [ + 'headers' => [ + 'Authorization' => 'Bearer ' . session()->get('token') + ] ]); } catch (RequestException $e) { $this->isExpired($e); @@ -168,12 +259,22 @@ public function update(string $where, string $body) } } - private function isExpired(RequestException $e) + /** + * @param string $body + */ + public function store(string $body) { - if ($e->getCode() == 419/*fai il controllo del token*/) { - session()->invalidate(); - session()->flush(); - return redirect('login'); + try { + //dd($body); + $this->request->post('users', [ + 'headers' => [ + 'Authorization' => 'Bearer ' . session()->get('token') + ], + 'body' => $body + ]); + } catch (RequestException $e) { + $this->isExpired($e); + abort($e->getCode(), $e->getResponse()->getReasonPhrase()); } } @@ -182,6 +283,9 @@ private function isExpired(RequestException $e) // Mockup per un utente // Funzione da rimuovere in production + /** + * @return User + */ public function imJustAGuyDontBotherMe() { $user = new User(); diff --git a/config/app.php b/config/app.php index 8927ba17..999f94ab 100644 --- a/config/app.php +++ b/config/app.php @@ -232,4 +232,5 @@ ], + 'api' => env('API_URL'), ]; diff --git a/package-lock.json b/package-lock.json index e7d3de7f..b7404e91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4752,24 +4752,24 @@ } }, "@jest/transform": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.1.0.tgz", - "integrity": "sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ==", + "version": "25.2.4", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.2.4.tgz", + "integrity": "sha512-6eRigvb+G6bs4kW5j1/y8wu4nCrmVuIe0epPBbiWaYlwawJ8yi1EIyK3d/btDqmBpN5GpN4YhR6iPPnDmkYdTA==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^25.1.0", + "@jest/types": "^25.2.3", "babel-plugin-istanbul": "^6.0.0", "chalk": "^3.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.3", - "jest-haste-map": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-util": "^25.1.0", + "jest-haste-map": "^25.2.3", + "jest-regex-util": "^25.2.1", + "jest-util": "^25.2.3", "micromatch": "^4.0.2", "pirates": "^4.0.1", - "realpath-native": "^1.1.0", + "realpath-native": "^2.0.0", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" @@ -4816,6 +4816,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -4834,9 +4840,9 @@ } }, "@jest/types": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", - "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.2.3.tgz", + "integrity": "sha512-6oLQwO9mKif3Uph3RX5J1i3S7X7xtDHWBaaaoeKw8hOzV6YUd0qDcYcHZ6QXMHDIzSr7zzrEa51o2Ovlj6AtKQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -5482,9 +5488,9 @@ } }, "apexcharts": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.17.0.tgz", - "integrity": "sha512-h72kJQzX/OWsdWPD/WTWYUctmZVKcuNzqca2MxXb9lmauD/5R+IAKLMHpsDeSMTA9UcmedkWIcjnnWvYrVUzhw==", + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.17.1.tgz", + "integrity": "sha512-zfeyHGSkz8iyCk461mbq5cpjhkGiTXz+NaVivCAbeqqRARg7oDDrwLD6MK+mA5Zl5MBqS2lXlcJP56C4rxq3BA==", "requires": { "svg.draggable.js": "^2.2.2", "svg.easing.js": "^2.0.0", @@ -5899,16 +5905,16 @@ } }, "babel-jest": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.1.0.tgz", - "integrity": "sha512-tz0VxUhhOE2y+g8R2oFrO/2VtVjA1lkJeavlhExuRBg3LdNJY9gwQ+Vcvqt9+cqy71MCTJhewvTB7Qtnnr9SWg==", + "version": "25.2.4", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.2.4.tgz", + "integrity": "sha512-+yDzlyJVWrqih9i2Cvjpt7COaN8vUwCsKGtxJLzg6I0xhxD54K8mvDUCliPKLufyzHh/c5C4MRj4Vk7VMjOjIg==", "dev": true, "requires": { - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", + "@jest/transform": "^25.2.4", + "@jest/types": "^25.2.3", "@types/babel__core": "^7.1.0", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^25.1.0", + "babel-preset-jest": "^25.2.1", "chalk": "^3.0.0", "slash": "^3.0.0" }, @@ -6030,9 +6036,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.1.0.tgz", - "integrity": "sha512-oIsopO41vW4YFZ9yNYoLQATnnN46lp+MZ6H4VvPKFkcc2/fkl3CfE/NZZSmnEIEsJRmJAgkVEK0R7Zbl50CpTw==", + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.2.1.tgz", + "integrity": "sha512-HysbCQfJhxLlyxDbKcB2ucGYV0LjqK4h6dBoI3RtFuOxTiTWK6XGZMsHb0tGh8iJdV4hC6Z2GCHzVvDeh9i0lQ==", "dev": true, "requires": { "@types/babel__traverse": "^7.0.6" @@ -6454,14 +6460,14 @@ } }, "babel-preset-jest": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.1.0.tgz", - "integrity": "sha512-eCGn64olaqwUMaugXsTtGAM2I0QTahjEtnRu0ql8Ie+gDWAc1N6wqN0k2NilnyTunM69Pad7gJY7LOtwLimoFQ==", + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.2.1.tgz", + "integrity": "sha512-zXHJBM5iR8oEO4cvdF83AQqqJf3tJrXy3x8nfu2Nlqvn4cneg4Ca8M7cQvC5S9BzDDy1O0tZ9iXru9J6E3ym+A==", "dev": true, "requires": { "@babel/plugin-syntax-bigint": "^7.0.0", "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^25.1.0" + "babel-plugin-jest-hoist": "^25.2.1" } }, "babel-runtime": { @@ -13379,22 +13385,50 @@ "dev": true }, "jest-haste-map": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.1.0.tgz", - "integrity": "sha512-/2oYINIdnQZAqyWSn1GTku571aAfs8NxzSErGek65Iu5o8JYb+113bZysRMcC/pjE5v9w0Yz+ldbj9NxrFyPyw==", + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.2.3.tgz", + "integrity": "sha512-pAP22OHtPr4qgZlJJFks2LLgoQUr4XtM1a+F5UaPIZNiCRnePA0hM3L7aiJ0gzwiNIYwMTfKRwG/S1L28J3A3A==", "dev": true, "requires": { - "@jest/types": "^25.1.0", + "@jest/types": "^25.2.3", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", "graceful-fs": "^4.2.3", - "jest-serializer": "^25.1.0", - "jest-util": "^25.1.0", - "jest-worker": "^25.1.0", + "jest-serializer": "^25.2.1", + "jest-util": "^25.2.3", + "jest-worker": "^25.2.1", "micromatch": "^4.0.2", "sane": "^4.0.3", - "walker": "^1.0.7" + "walker": "^1.0.7", + "which": "^2.0.2" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "jest-worker": { + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.2.1.tgz", + "integrity": "sha512-IHnpekk8H/hCUbBlfeaPZzU6v75bqwJp3n4dUrQuQOAgOneI4tx3jV2o8pvlXnDfcRsfkFIUD//HWXpCmR+evQ==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-jasmine2": { @@ -13703,9 +13737,9 @@ "dev": true }, "jest-regex-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.1.0.tgz", - "integrity": "sha512-9lShaDmDpqwg+xAd73zHydKrBbbrIi08Kk9YryBEBybQFg/lBWR/2BDjjiSE7KIppM9C5+c03XiDaZ+m4Pgs1w==", + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.1.tgz", + "integrity": "sha512-wroFVJw62LdqTdkL508ZLV82FrJJWVJMIuYG7q4Uunl1WAPTf4ftPKrqqfec4SvOIlvRZUdEX2TFpWR356YG/w==", "dev": true }, "jest-resolve": { @@ -15549,9 +15583,9 @@ } }, "jest-serializer": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.1.0.tgz", - "integrity": "sha512-20Wkq5j7o84kssBwvyuJ7Xhn7hdPeTXndnwIblKDR2/sy1SUm6rWWiG9kSCgJPIfkDScJCIsTtOKdlzfIHOfKA==", + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.2.1.tgz", + "integrity": "sha512-fibDi7M5ffx6c/P66IkvR4FKkjG5ldePAK1WlbNoaU4GZmIAkS9Le/frAwRUFEX0KdnisSPWf+b1RC5jU7EYJQ==", "dev": true }, "jest-snapshot": { @@ -15604,15 +15638,15 @@ } }, "jest-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.1.0.tgz", - "integrity": "sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw==", + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.2.3.tgz", + "integrity": "sha512-7tWiMICVSo9lNoObFtqLt9Ezt5exdFlWs5fLe1G4XLY2lEbZc814cw9t4YHScqBkWMfzth8ASHKlYBxiX2rdCw==", "dev": true, "requires": { - "@jest/types": "^25.1.0", + "@jest/types": "^25.2.3", "chalk": "^3.0.0", "is-ci": "^2.0.0", - "mkdirp": "^0.5.1" + "make-dir": "^3.0.0" }, "dependencies": { "ansi-styles": { diff --git a/package.json b/package.json index 9c69c702..448755fd 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "@vue/test-utils": "^1.0.0-beta.32", "axios": "^0.19", "babel-core": "^7.0.0-bridge.0", - "babel-jest": "^25.1.0", + "babel-jest": "^25.2.4", "babel-loader": "^8.1.0", "babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-polyfill": "^6.26.0", @@ -45,7 +45,7 @@ "vue-template-compiler": "^2.6.10" }, "dependencies": { - "apexcharts": "^3.17.0", + "apexcharts": "^3.17.1", "vue-apexcharts": "^1.5.2" }, "jest": { diff --git a/public/js/script.js b/public/js/script.js new file mode 100644 index 00000000..5efd34e6 --- /dev/null +++ b/public/js/script.js @@ -0,0 +1,42 @@ +const sensorsList = document.querySelector("#sensorsList"); +const addSensor = document.querySelector("#addSensor"); +const addDevice = document.querySelector("#addDevice"); +const form = document.querySelector("#sensorForm"); +let numSensor = 1; + +addSensor.addEventListener("click", (e) => { + e.preventDefault(); + const sensorIdValue = document.querySelector("#inputSensorId").value; + const sensorTypeValue = document.querySelector("#inputSensorType").value; + if (sensorIdValue !== "" && sensorTypeValue !== "") { + sensorsList.innerHTML += ` +
{{ $_SERVER['REMOTE_ADDR'] }}
Puoi modificare il dispositivo inserendo le informazioni elencate in seguito:
+ + @endcan +Puoi creare un nuovo sensore inserendo le informazioni elencate in seguito:
+ + @endcan +Puoi modificare un dispositivo inserendo le informazioni elencate in seguito:
+ + @endcan +Puoi creare un nuovo sensore inserendo le informazioni elencate in seguito:
+ + @endcan +Status | -Dispositivo | -Nome | -# Sensori | -Ente | -- | - | ||
---|---|---|---|---|---|---|---|---|
Status | -Dispositivo | -Nome | -# Sensori | -Ente | -- | - |
Id | +Nome | +Gateway | +Numero di sensori | +Frequenza | +Status | ++ | + | |
---|---|---|---|---|---|---|---|---|
Id | +Nome | +Gateway | +Numero di sensori | +Frequenza | +Status | ++ | + | |
1 | +Termostato | +US-Gateway | +4 | +0.5 | +Attivo | ++ + + + Dettagli + + | ++ + + + Modifica + + | +|
2 | +Grattugia | +US-Gateway | +2 | +1 | +Attivo | ++ + + + Dettagli + + | ++ + + + Modifica + + | +|
3 | +Fresa | +US-Gateway | +1 | +03 | +Attivo | ++ + + + Dettagli + + | ++ + + + Modifica + + | +|
Attivo | {{$device->deviceId}} | {{$device->name}} | -{{ "TBD" }} | -{{ "TBD" }} | +{{count($device->getSensors())}} | +{{$device->getEntity()->getName()}} | ++ + + + Sensori + + | ++ + + + Dettagli + + | +
Id | +Nome | +Gateway | +Numero di Sensori | +Frequenza | +Status | ++ | + |
---|---|---|---|---|---|---|---|
Id | +Nome | +Gateway | +Numero di Sensori | +Frequenza | +Status | ++ | + |
1 | +Termostato | +DE-Gateway | +4 | +0.5 | +Attivo | ++ + + + Dettagli + + | ++ + + + Modifica + + | +
2 | +Grattugia | +DE-Gateway | +2 | +1 | +Disattivo | ++ + + + Dettagli + + | ++ + + + Modifica + + | +
3 | +Fresa | +DE-Gateway | +1 | +03 | +Attivo | ++ + + + Dettagli + + | ++ + + + Modifica + + | +
Attivo | +{{$device->deviceId}} | +{{$device->name}} | +{{count($device->getSensors())}} | +{{$device->getEntity()->getName()}} | - + Sensori | - + Dettagli |
Id | +Nome | +Gateway | +Numero di sensori | +Frequenza | +Status | +
---|---|---|---|---|---|
1 | +Termostato | +US-Gateway | +4 | +0.5 | +Attivo | +
Id sensore | +Id dispositivo | +Tipologia | +Grafico | +
---|---|---|---|
Id sensore | +Id dispositivo | +Tipologia | +Grafico | +
1 | +1 | +Temperatura | ++ + + + Mostra grafico + + | +
Status | +ID | +ID interno | +ID dispositivo | +Tipo | ++ |
---|---|---|---|---|---|
Status | +ID | +ID interno | +ID dispositivo | +Tipo | ++ |
Attivo | +{{$sensor->sensorId}} | +{{$sensor->deviceSensorId}} | +{{$sensor->deviceId}} | +{{$sensor->type}} | ++ + + + Dettagli + + | +
+
*Per attivare l'autenticazione a due fattori è necessario inserire il proprio username Telegram
e avviare il bot direttamente dall'applicazione, inserendo il comando /start
in chat.