Skip to content
Permalink
Browse files

v.0.5-beta [Версия для тестирования]

* Добавлена поддержка умения **temperature**.
* Добавлена возможность переопределить диапазон значений и шаг изменения величины для умений volume, channel, temperature, brightness.
* Изменено время жизни токена доступа OAuth с 12 часов до 7 дней.
  • Loading branch information...
skysilver-lab committed Jun 29, 2019
1 parent e965fae commit dd4518bd5720ea42765149f682242330fecc09b3
@@ -29,12 +29,16 @@ ____
| # | Метрика (умение) | Описание | Значения в модуле | Значения от Яндекс |
| -------- | -------- | -------- | -------- | -------- |
| 1 | on | Включить/выключить (1 - включено, 0 выключено). | 1 и 0 | true и false |
| 2 | volume | Громкость (проценты). | 1 - 100 | 1 - 100, либо +1/-1 |
| 3 | channel | ТВ-канал. | № канала | № канала, либо +1/-1 |
| 4 | temperature_k | Температура цвета (кельвины). | 2700 - 9000 | 2700 - 9000 |
| 5 | mute | Режим без звука (1 - включено, 0 выключено). | 1 и 0 | true и false |
| 6 | rgb | Цвет в формате RGB (hex). | 000000 - FFFFFF | 0 - 16777215 |
| 7 | brightness | Яркость (проценты). | 1 - 100 | 1 - 100 |
| 2 | volume | Громкость (проценты). | 1 - 100 (\*) | 1 - 100, либо +1/-1 |
| 3 | channel | ТВ-канал. | № канала (\*) | № канала, либо +1/-1 |
| 4 | temperature | Температура (градусы цельсия). | 1 - 100 (\*) | °C |
| 5 | temperature_k | Температура цвета (кельвины). | 2700 - 9000 | 2700 - 9000 |
| 6 | mute | Режим без звука (1 - включено, 0 выключено). | 1 и 0 | true и false |
| 7 | rgb | Цвет в формате RGB (hex). | 000000 - FFFFFF | 0 - 16777215 |
| 8 | brightness | Яркость (проценты). | 1 - 100 (\*) | 1 - 100 |


\* Имеется возможность переопределить диапазон значений и шаг изменения.

____
### **Требования**
@@ -27,7 +27,7 @@
$storage = new OAuth2\Storage\MajordomoPdo(array('dsn' => $dsn, 'username' => DB_USER, 'password' => DB_PASSWORD));
$server = new OAuth2\Server($storage, array('access_lifetime' => 12*3600));
$server = new OAuth2\Server($storage, array('access_lifetime' => 7*24*3600));
$server->addGrantType(new OAuth2\GrantType\ClientCredentials($storage));
@@ -91,13 +91,30 @@
'instance_name' => 'channel',
'description' => 'ТВ-канал',
'capability' => 'range',
'default_value' => 1
],/*
'default_value' => 1,
'retrievable' => false,
'parameters' => [
'range' => [
'min' => 0,
'max' => 999,
'precision' => 1
]
]
],
'temperature' => [
'instance_name' => 'temperature',
'description' => 'Температура',
'capability' => 'range'
],*/
'capability' => 'range',
'default_value' => 20,
'parameters' => [
'unit' => 'unit.temperature.celsius',
'range' => [
'min' => 1,
'max' => 100,
'precision' => 1
]
]
],
'temperature_k' => [
'instance_name' => 'temperature_k',
'description' => 'Цветовая температура',
@@ -3,7 +3,7 @@
* Главный класс модуля Yandex Home
* @author <skysilver.da@gmail.com>
* @copyright 2019 Agaphonov Dmitri aka skysilver <skysilver.da@gmail.com> (c)
* @version 0.4b 2019/06/20
* @version 0.5b 2019/07/01
*/
const PREFIX_CAPABILITIES = 'devices.capabilities.';
@@ -337,6 +337,7 @@ function edit_yandexhome_devices(&$out, $id)
// Поддерживаемые метрики (возможности) устройств.
$out['DEVICES_INSTANCE'] = array_values($this->devices_instance);
$out['DEVICES_INSTANCE_JSON'] = json_encode($this->devices_instance, JSON_UNESCAPED_UNICODE);
// Список местоположений (комнат) в системе.
$out['LOCATIONS'] = SQLSelect('SELECT ID, TITLE FROM locations ORDER BY TITLE');
@@ -387,13 +388,16 @@ function edit_yandexhome_devices(&$out, $id)
$old_dev_traits = json_decode($rec['TRAITS'], true);
// Новые (в формате json).
$rec['TRAITS'] = gr('traits_json');
// Новые (в формате json).
// Новые (массив).
$new_dev_traits = json_decode($rec['TRAITS'], true);
if ($rec['TRAITS'] == '' || count($new_dev_traits) == 0) {
$out['ERR_TRAITS'] = 1;
$ok = 0;
}
// Конфигурация умений.
$devices_instance = json_decode(gr('instance_json'), true);
// Если обязательные поля заполнены, то сохраняем конфигурацию устройства.
if ($ok) {
if ($rec['ID']) {
@@ -403,8 +407,8 @@ function edit_yandexhome_devices(&$out, $id)
foreach ($new_dev_traits as $trait) {
$parameters = [];
$trait_type = PREFIX_CAPABILITIES . $this->devices_instance[$trait['type']]['capability'];
if (isset($this->devices_instance[$trait['type']]['parameters'])) {
$parameters = $this->devices_instance[$trait['type']]['parameters'];
if (isset($devices_instance[$trait['type']]['parameters'])) {
$parameters = $devices_instance[$trait['type']]['parameters'];
if ($trait['type'] != 'rgb' && $trait['type'] != 'temperature_k') {
$parameters['instance'] = $trait['type'];
}
@@ -421,9 +425,15 @@ function edit_yandexhome_devices(&$out, $id)
if ($check && $trait_type == PREFIX_CAPABILITIES.'color_setting') {
$traits[$check]['parameters'] = array_merge ($traits[$check]['parameters'], $parameters);
} else {
if (isset($this->devices_instance[$trait['type']]['retrievable'])) {
$retrievable = $this->devices_instance[$trait['type']]['retrievable'];
} else {
$retrievable = true;
}
$traits[] = [
'type' => $trait_type,
'parameters' => $parameters
'parameters' => $parameters,
'retrievable' => $retrievable
];
}
}
@@ -9,7 +9,7 @@ <h4 class="modal-title">Yandex Home</h4>
<div class="modal-body" style="padding-bottom: 1px;">
<div class="float-right">
<img src="../img/modules/yandexhome.png" width="48" height="48">
<br><br><p><b>v.0.4b</b><br>20.06.19</p>
<br><br><p><b>v.0.5b</b><br>01.07.19</p>
</div>
<p class="float-left">
Модуль поддержки <b>личных</b> (приватных) навыков для платформы умного дома <b>Яндекс</b>.<br><br>
@@ -28,7 +28,7 @@ <h4 class="modal-title">Yandex Home</h4>
</ul>
</p>
<h6>
Благодарности: <b>Vit</b>, <b>iden</b>, <b>Xor</b>, <b>ImHuman</b>, <b>AntPino</b>, <b>tarasfrompir</b>, <b>Sergey.Chek</b>, <b>webms</b>, <b>Anton_kulibin</b>, <b>TurburatoR</b>, <b>denis_1988_06</b>, <b>louso</b>, <b>Yden_nn</b>, <b>C_3AXAPOB</b>, <b>AlexAl77</b>, <b>cheetah</b>, <b>ahelper</b>, <b>dubler78</b>, <b>VlasVic</b>.
Благодарности: <b>Vit</b>, <b>iden</b>, <b>Xor</b>, <b>ImHuman</b>, <b>AntPino</b>, <b>tarasfrompir</b>, <b>Sergey.Chek</b>, <b>webms</b>, <b>Anton_kulibin</b>, <b>TurburatoR</b>, <b>denis_1988_06</b>, <b>louso</b>, <b>Yden_nn</b>, <b>C_3AXAPOB</b>, <b>AlexAl77</b>, <b>cheetah</b>, <b>ahelper</b>, <b>dubler78</b>, <b>VlasVic</b>, <b>sbazhukov</b>.
</h6>
</div>
<div class="modal-footer" style="margin-top: 1px;">
@@ -99,7 +99,8 @@
<label class="col-lg-3 control-label"></label>
<div class="col-lg-4">
<table id="traits_table" class="table"></table>
<input type="hidden" class="form-control" name="traits_json" id="traits_json" value="{}">
<input type="hidden" name="traits_json" id="traits_json" value="{}">
<input type="hidden" name="instance_json" id="instance_json" value="{}">
</div>
</div>
<div class="form-group">
@@ -117,8 +118,15 @@
<div>
<pre id="objects_json" style="display:none;">[#OBJECTS#]</pre>
<!--# <pre>[#CONFIG#]</pre> #-->
<!--# <pre>[#TRAITS#]</pre> #-->
</div>

<style>
.popover {
max-width: 250px;
}
</style>

<script type="text/javascript">
var script = document.createElement('script');
@@ -131,13 +139,23 @@
var traits_list = {};
var objects_list = [];
var objects_options = '';
var instance_list = {};
var isPopover = false;
// Получаем список метрик в формате JSON.
var traits_json = '[#TRAITS#]';
// Получаем список метрик в формате JSON.
var objects_json = $('#objects_json').text();
// Получаем массив поддерживаемых умений.
var instance_list = tryParseJSON('[#DEVICES_INSTANCE_JSON#]');
saveInstanceList();
// Получаем конфиг устройства в формате JSON.
var dev_config = tryParseJSON('[#CONFIG#]');
script.onload = function() {
// После подгрузки js-файла перерисуем элементы select.
$('.selectpicker').selectpicker('render');
@@ -176,11 +194,41 @@
}
}
if (dev_config !== '' && dev_config !== false) {
let capabilities = dev_config.capabilities;
if (capabilities.length > 0) {
for (key in capabilities) {
if (typeof(capabilities[key].parameters.instance) != 'undefined' && capabilities[key].parameters.instance !== null) {
let linked_type = capabilities[key].parameters.instance;
if (instance_list[linked_type].capability === 'range') {
if (typeof(capabilities[key].parameters.range) != 'undefined' && capabilities[key].parameters.range !== null) {
min_value = capabilities[key].parameters.range['min'];
max_value = capabilities[key].parameters.range['max'];
precision_value = capabilities[key].parameters.range['precision'];
instance_list[linked_type].parameters.range['min'] = min_value;
instance_list[linked_type].parameters.range['max'] = max_value;
instance_list[linked_type].parameters.range['precision'] = precision_value;
}
}
}
}
saveInstanceList();
}
}
$('body').popover({
selector: '.popover_instance',
container: 'body',
placement: 'top',
html: true
});
//console.log('stop');
}
function renderTraitsTable() {
$('#traits_table tr').remove();
isPopover = false;
for (key in traits_list) {
if (traits_list.hasOwnProperty(key)) {
let linked_type = traits_list[key].type;
@@ -192,6 +240,9 @@
objects_list[linked_object] = '';
}
}
if (isPopover) {
initPopovers();
}
}
function renderPropertySelectbox(id, object = '', selected = '') {
@@ -242,7 +293,18 @@
// Строка с наименование метрики.
let row = $('<tr id="table_titlerow' + linked_type + '"/>');
$('#traits_table').append(row);
row.append($(`<td colspan="3">${linked_description} (${linked_type})</td>`));
let range_options = '';
if (instance_list[linked_type].capability === 'range') {
if (typeof(instance_list[linked_type].parameters) != 'undefined' && instance_list[linked_type].parameters !== null) {
range_options =
`<span id="options${linked_type}" data-instance="${linked_type}" class="btn btn-link popover_instance" style="max-width: 250px;" data-toggle="popover" title="Дополнительные опции" data-content=''><i class="glyphicon glyphicon-cog"></i></span>`;
isPopover = true;
}
}
row.append($(`<td colspan="3">${linked_description} (${linked_type}) ${range_options}</td>`));
// Строка с полями выбора объекта и свойства.
row = $('<tr id="table_mainrow' + linked_type + '"/>');
@@ -277,9 +339,15 @@
traits_list[trait_type].linked_property = '';
saveTraitsList();
isPopover = false;
// Обновляем таблицу метрик.
addTraitRow(trait_type, trait_description, '', '');
if (isPopover) {
initPopovers();
}
// Сбрасываем значение список выбора метрик на дефолтное (пустое).
$('#select_trait').selectpicker('val', '');
// Делаем неактивными пункты в списке выбора метрик.
@@ -308,7 +376,88 @@
function saveTraitsList() {
$('#traits_json').val(JSON.stringify(traits_list));
//console.log(JSON.stringify(traits_list));
}
function getInstanceOptions(linked_type, init) {
let min_value = '';
let max_value = '';
let precision_value = '';
if (instance_list[linked_type].capability === 'range') {
if (typeof(instance_list[linked_type].parameters) != 'undefined' && instance_list[linked_type].parameters !== null) {
min_value = instance_list[linked_type].parameters.range['min'];
max_value = instance_list[linked_type].parameters.range['max'];
precision_value = instance_list[linked_type].parameters.range['precision'];
}
}
let optionsAsString = `
<div class="input-group input-group-sm">
<span class="input-group-addon" id="basic-addon1">Min&nbsp&nbsp</span>
<input type="text" class="form-control" aria-describedby="basic-addon1" id="min_value${linked_type}" value="${min_value}">
</div>
<div style="line-height: 50%;">&nbsp</div>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="basic-addon2">Max&nbsp</span>
<input type="text" class="form-control" aria-describedby="basic-addon2" id="max_value${linked_type}" value="${max_value}">
</div>
<div style="line-height: 50%;">&nbsp</div>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="basic-addon3">Step</span>
<input type="text" class="form-control" aria-describedby="basic-addon3" id="precision_value${linked_type}" value="${precision_value}">
</div>
<div style="line-height: 50%;">&nbsp</div>
<div class="text-center">
<span id="${linked_type}" class="btn btn-success btn-sm" onclick="saveInstanceOptions(this);"><i class="glyphicon glyphicon-ok"></i></span>&nbsp
<span id="${linked_type}" class="btn btn-default btn-sm" onclick="closePopover(this);"><i class="glyphicon glyphicon-remove"></i></span>
</div>`;
return optionsAsString;
}
function saveInstanceOptions(o) {
linked_type = o.id;
let min_value = Number($('#min_value' + linked_type).val());
let max_value = Number($('#max_value' + linked_type).val());
let precision_value = Number($('#precision_value' + linked_type).val());
instance_list[linked_type].parameters.range['min'] = min_value;
instance_list[linked_type].parameters.range['max'] = max_value;
instance_list[linked_type].parameters.range['precision'] = precision_value;
saveInstanceList();
$('#options' + linked_type).popover('toggle');
}
function saveInstanceList() {
$('#instance_json').val(JSON.stringify(instance_list));
}
function initPopovers() {
let $popovers = $('[data-toggle="popover"]');
$popovers.popover('destroy');
$popovers.popover({
selector: '.popover_instance',
container: 'body',
placement: 'top',
html: true
});
$popovers.on('show.bs.popover', function () {
let linked_type = $(this).attr('data-instance');
let content = getInstanceOptions(linked_type);
$('#options' + linked_type).attr('data-content', content);
});
}
function closePopover(o) {
linked_type = o.id;
$('#options' + linked_type).popover('toggle');
}
function linkedObjectChaged(id, selected_object) {
@@ -160,15 +160,17 @@ <h4>Справка</h4>
</thead>
<tbody>
<tr><td><b>on</b></td><td>Включить/выключить (1 - включено, 0 выключено).</td><td>1 и 0</td><td>true и false</td></tr>
<tr><td><b>volume</b></td><td>Громкость (проценты).</td><td>1 - 100</td><td>1 - 100, либо +1/-1</td></tr>
<tr><td><b>channel</b></td><td>ТВ-канал.</td><td>№ канала</td><td>№ канала, либо +1/-1</td></tr>
<tr><td><b>volume</b></td><td>Громкость (проценты).</td><td>1 - 100 (*)</td><td>1 - 100, либо +1/-1</td></tr>
<tr><td><b>channel</b></td><td>ТВ-канал.</td><td>№ канала (*)</td><td>№ канала, либо +1/-1</td></tr>
<tr><td><b>temperature</b></td><td>Температура (градусы цельсия).</td><td>1 - 100 (*)</td><td>°C</td></tr>
<tr><td><b>temperature_k</b></td><td>Температура цвета (кельвины).</td><td>2700 - 9000</td><td>2700 - 9000</td></tr>
<tr><td><b>mute</b></td><td>Режим без звука (1 - включено, 0 выключено).</td><td>1 и 0</td><td>true и false</td></tr>
<tr><td><b>rgb</b></td><td>Цвет в формате RGB (hex).</td><td>000000 - FFFFFF</td><td>0 - 16777215</td></tr>
<tr><td><b>brightness</b></td><td>Яркость (проценты).</td><td>1 - 100</td><td>1 - 100</td></tr>
<tr><td><b>brightness</b></td><td>Яркость (проценты).</td><td>1 - 100 (*)</td><td>1 - 100</td></tr>
</tbody>
</table>
</div>
<div>* Имеется возможность переопределить диапазон значений и шаг изменения.</div>
</div>
</div>
</div>

0 comments on commit dd4518b

Please sign in to comment.
You can’t perform that action at this time.