Newer
Older
smart-home-server / server / ControlScripts / SpotlightsScope.php
<?php

namespace ControlScripts;

use \SHServ\Entities\Device;

class SpotlightsScope extends \SHServ\Middleware\ControlScripts implements \SHServ\Implements\ControlScriptsInterface {
	protected $aliases = [
		0 => "spotlight_main_back_1", 
		1 => "spotlight_main_back_2", 
		2 => "spotlight_main_front_1"
	];

	public function register_events_handlers(): void {
		$this -> backdoor_btns_handlers();
	}

	public function register_actions_scripts(): void {
		$this -> add_action_script([
			"alias" => "spotlights_on",
			"name" => "All Spotlights On",
			"description" => "Включить все прожекторы",
			"author" => "Eugene Sukhodolskiy"
		], function($params) {
			return $this -> all_spotlight_switch(true);
		});

		$this -> add_action_script([
			"alias" => "spotlights_off",
			"name" => "All Spotlights Off",
			"description" => "Выключить все прожекторы",
			"author" => "Eugene Sukhodolskiy"
		], function($params) {
			return $this -> all_spotlight_switch(false);
		});
	}

	public function register_regular_scripts(): void {
		$this -> add_regular_script([
			"alias" => "spotlights_by_time",
			"name" => "Spotlights by Time",
			"description" => "Управление уличными прожекторами по времени",
			"author" => "Eugene Sukhodolskiy"
		], function () {
			$tz = new \DateTimeZone('Europe/Kyiv');

			$now = new \DateTime('now', $tz);
			$limit = new \DateTime('9:00', $tz);

			if ($now >= $limit) {
				$this -> all_spotlight_switch(false);
			}
		});
	}

	// ACTIONS
	
	protected function all_spotlight_switch(Bool $state = false): Array {
		$results = [];
		$btns_block_api = $this -> devices() -> by_alias("buttons_backdoor") -> device_api();

		foreach($this -> aliases as $btn_channel => $alias) { 
			$relay_api = $this -> devices() -> by_alias($alias) -> device_api();
			$result = false;

			if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay) {
				$status = $relay_api -> get_status();

				if(isset($status["channels"][0]["state"]) and $status["channels"][0]["state"] != ($state ? "on" : "off")) {
					$result = $relay_api -> set_state($state);
					$this -> sync_relay_channel_btn_channel($relay_api, $btns_block_api, 0, $btn_channel);
				}
			}

			$results[$alias] = $result;
		}

		return [
			"devices" => $results
		];
	}

	// EVENTS HANDLERS
	
	/**
	 * Helper.
	 * Нужен для синхронизации состояния реле и канала блока кнопок.
	 * TODO: Это нужно оформить как официальный хелпер
	 * @param  Relay       $relay  
	 * @param  Button      $btn
	 * @param  int|integer $relay_channel
	 * @param  int|integer $btn_channel
	 * @return void
	 */
	public function sync_relay_channel_btn_channel(\SHServ\Tools\DeviceAPI\Relay $relay_api, \SHServ\Tools\DeviceAPI\Button $btn_block_api, int $relay_channel = 0, int $btn_channel = 0): void {
		$relay_channels = ($relay_api -> get_status())["channels"];

		$btn_block_api -> set_channel_state(
			$relay_channels[$relay_channel]["state"] == "on" ? "enabled" : "disabled", 
			$btn_channel
		);
	}

	protected function backdoor_btns_handlers() {
		foreach($this -> aliases as $btn_channel => $relay_alias) { 
			$this -> add_event_handler("button@buttons_backdoor({$btn_channel}).press", function(Device $btns_block, Array $data) use ($btn_channel, $relay_alias) {
				$btns_block_api = $btns_block -> device_api();
				$relay_api = $this -> devices() -> by_alias($relay_alias) -> device_api();

				if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay and $btns_block_api instanceof \SHServ\Tools\DeviceAPI\Button) {
					$relay_api -> toggle_channel(0);
					$this -> sync_relay_channel_btn_channel($relay_api, $btns_block_api, 0, $btn_channel);
				}
			});
		}
	}
}