Skip to content

Commit

Permalink
v.1.7-beta
Browse files Browse the repository at this point in the history
* Добавлена поддержка пылесоса Mi Roborock S50/S51:
  * получение текущего статуса;
  * получение сведений о расходных материалах;
  * получение сведений об уборке;
  * получения сведений об ошибках;
  * управление через метрику command:
    * app_start - начать уборку;
    * app_stop - остановить уборку;
    * app_pause - приостановить уборку;
    * app_spot - прибрать участок вокруг пылесоса;
    * app_charge - отправить на базу и встать на зарядку;
    * find_me - посигналить, чтобы найти пылесос;
    * и другие.
* Добавлена поддержка лампочек (спотов) Philips Zhirui Downlight:
  * получение текущего статуса и параметров (power, bright, cct, snm, dv);
  * включение/выключение (power);
  * управление яркостью (bright);
  * управление цветовой температурой (cct);
  * управление сценами (snm);
  * управление таймеров отключения (dv).
* Добавлена поддержка розетки Mi Smart Socket Plug with 2 USB:
  * получение текущего статуса и параметров (power, load_power, temperature, usb_on, wifi_led);
  * включение/выключение (power);
  * потребляемая мощность (load_power);
  * внутрення температура (temperature);
  * управление USB-портами (usb_on);
  * управление wifi-индикатором (wifi_led).
* Для увлажнителя добавлена метрика limit_hum - уровень верхнего предела увлажнения.
* Для очистителя воздуха добавлена функция сброса ресурса фильтра.
* Добавлено изображение замка Aqara Lock.
* Обновлены описания статуса и ошибок у пылесосов.
* Исправлено расположение кнопки About.
* Меню выбора типа устройств теперь с картинками.
  • Loading branch information
skysilver-lab committed May 31, 2018
1 parent a88c654 commit ee5a5c5
Show file tree
Hide file tree
Showing 25 changed files with 354 additions and 141 deletions.
12 changes: 9 additions & 3 deletions modules/xiaomimiio/miio_devices_edit.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/*
* @author <[email protected]>
* @copyright 2017-2018 Agaphonov Dmitri aka skysilver <[email protected]> (c)
* @version 1.5b
* @version 1.7b
*/

if ($this->owner->name == 'panel') {
Expand Down Expand Up @@ -47,7 +47,7 @@
}

$commands = array('online', 'command', 'message');
if (($rec['DEVICE_TYPE'] == 'lumi.gateway.v3') || ($rec['DEVICE_TYPE'] == 'lumi.acpartner.v3')) {
if (($rec['DEVICE_TYPE'] == 'lumi.gateway.v3') || ($rec['DEVICE_TYPE'] == 'lumi.acpartner.v3')) {
$commands[] = 'add_program';
$commands[] = 'del_program';
}
Expand Down Expand Up @@ -119,7 +119,7 @@
if ($dev_type != '') {
$rec['DEVICE_TYPE'] = $dev_type;
SQLUpdate($table_name, $rec);
$this->requestStatus($rec['ID']);
$this->requestStatus($rec['ID']);
}
}
}
Expand Down Expand Up @@ -196,6 +196,7 @@
elseif ($properties[$i]['TITLE'] == 'illumination') $properties[$i]['SDEVICE_TYPE'] = 'sensor_light';
elseif ($properties[$i]['TITLE'] == 'current') $properties[$i]['SDEVICE_TYPE'] = 'sensor_current';
elseif ($properties[$i]['TITLE'] == 'power_consume_rate') $properties[$i]['SDEVICE_TYPE'] = 'sensor_power';
elseif ($properties[$i]['TITLE'] == 'load_power') $properties[$i]['SDEVICE_TYPE'] = 'sensor_power';
elseif ($properties[$i]['TITLE'] == 'aqi') $properties[$i]['SDEVICE_TYPE'] = 'sensor_state';
elseif ($properties[$i]['TITLE'] == 'average_aqi') $properties[$i]['SDEVICE_TYPE'] = 'sensor_state';
elseif ($properties[$i]['TITLE'] == 'favorite_level') $properties[$i]['SDEVICE_TYPE'] = 'dimmer';
Expand All @@ -213,6 +214,11 @@
elseif ($properties[$i]['TITLE'] == 'hue') $properties[$i]['SDEVICE_TYPE'] = 'sensor_state';
elseif ($properties[$i]['TITLE'] == 'sat') $properties[$i]['SDEVICE_TYPE'] = 'sensor_state';
elseif ($properties[$i]['TITLE'] == 'color_mode') $properties[$i]['SDEVICE_TYPE'] = 'sensor_state';
elseif ($properties[$i]['TITLE'] == 'snm') $properties[$i]['SDEVICE_TYPE'] = 'sensor_state';
elseif ($properties[$i]['TITLE'] == 'dv') $properties[$i]['SDEVICE_TYPE'] = 'sensor_state';
elseif ($properties[$i]['TITLE'] == 'bl') $properties[$i]['SDEVICE_TYPE'] = 'sensor_state';
elseif ($properties[$i]['TITLE'] == 'ac') $properties[$i]['SDEVICE_TYPE'] = 'sensor_state';
elseif ($properties[$i]['TITLE'] == 'limit_hum') $properties[$i]['SDEVICE_TYPE'] = 'sensor_humidity';
}
}
$out['PROPERTIES'] = $properties;
Expand Down
109 changes: 69 additions & 40 deletions modules/xiaomimiio/xiaomimiio.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* @package project
* @author <[email protected]>
* @copyright 2017-2018 Agaphonov Dmitri aka skysilver <[email protected]> (c)
* @version 1.6b
* @version 1.7b
*/

define ('MIIO_YEELIGHT_WHITE_BULB_PROPS', 'power,bright,flow_params,flowing');
Expand All @@ -26,20 +26,20 @@
define ('MIIO_ZIMI_POWERSTRIP_2_PROPS', 'power,temperature,current,power_consume_rate,wifi_led');

define ('MIIO_ZHIMI_HUMIDIFIER_PROPS', 'power,humidity,temp_dec,mode,led_b,buzzer');
define ('MIIO_ZHIMI_HUMIDIFIER_2_PROPS', 'power,humidity,temp_dec,mode,depth,speed,dry,use_time,led_b,buzzer,child_lock');
define ('MIIO_ZHIMI_HUMIDIFIER_2_PROPS', 'power,humidity,temp_dec,mode,depth,speed,dry,use_time,led_b,buzzer,child_lock,limit_hum');

define ('MIIO_ZHIMI_AIRPURIFIER_MA2_PROPS', 'power,aqi,average_aqi,humidity,temp_dec,bright,mode,favorite_level,filter1_life,use_time,purify_volume,led,buzzer,child_lock');

define ('MIIO_MIWIFISPEAKER_V1_PROPS', 'umi,volume,rel_time');

define ('MIIO_MIVACUUM_1_STATE_CODES', serialize (array('0' => 'Unknown',
define ('MIIO_MIVACUUM_1_STATE_CODES', serialize (array('0' => 'Unknown',
'1' => 'Initiating',
'2' => 'Sleeping',
'3' => 'Waiting',
'4' => 'Unknown',
'4' => 'Remote control active',
'5' => 'Cleaning',
'6' => 'Back to home',
'7' => 'Unknown',
'7' => 'Manual mode',
'8' => 'Charging',
'9' => 'Charging Error',
'10' => 'Pause',
Expand All @@ -48,9 +48,11 @@
'13' => 'Shutting down',
'14' => 'Updating',
'15' => 'Docking',
'16' => 'Going to target',
'17' => 'Zoned cleaning',
'100' => 'Full')));

define ('MIIO_MIVACUUM_1_ERROR_CODES', serialize (array('0' => 'No error',
define ('MIIO_MIVACUUM_1_ERROR_CODES', serialize (array('0' => 'No error',
'1' => 'Laser distance sensor error',
'2' => 'Collision sensor error',
'3' => 'Wheels on top of void, move robot',
Expand Down Expand Up @@ -470,7 +472,7 @@ function requestStatus($device_id) {

$device_rec = SQLSelectOne("SELECT * FROM miio_devices WHERE ID=" . (int)$device_id);

if ($device_rec['DEVICE_TYPE'] == 'philips.light.bulb') {
if (($device_rec['DEVICE_TYPE'] == 'philips.light.bulb') || ($device_rec['DEVICE_TYPE'] == 'philips.light.downlight')) {
//
$props = explode(',', MIIO_PHILIPS_LIGHT_BULB_PROPS);
$total = count($props);
Expand Down Expand Up @@ -510,7 +512,7 @@ function requestStatus($device_id) {
$props[$i] = '"' . $props[$i] . '"';
}
$this->addToQueue($device_id, 'get_prop', '[' . implode(',', $props) . ']');
} else if ($device_rec['DEVICE_TYPE'] == 'rockrobo.vacuum.v1') {
} else if (($device_rec['DEVICE_TYPE'] == 'rockrobo.vacuum.v1') || ($device_rec['DEVICE_TYPE'] == 'roborock.vacuum.s5')) {
//
$this->addToQueue($device_id, 'get_status');
sleep(1);
Expand All @@ -523,14 +525,18 @@ function requestStatus($device_id) {
$props[$i] = '"' . $props[$i] . '"';
}
$this->addToQueue($device_id, 'get_prop', '[' . implode(',', $props) . ']');
} elseif ($device_rec['DEVICE_TYPE'] == 'chuangmi.plug.v1') {
} elseif (($device_rec['DEVICE_TYPE'] == 'chuangmi.plug.v1') || ($device_rec['DEVICE_TYPE'] == 'chuangmi.plug.v3')) {
//
$props = explode(',', MIIO_CHUANGMI_PLUG_V1_PROPS);
$total = count($props);
for ($i = 0; $i < $total; $i++) {
$props[$i] = '"' . $props[$i] . '"';
}
$this->addToQueue($device_id, 'get_prop', '[' . implode(',', $props) . ']');
if ($device_rec['DEVICE_TYPE'] == 'chuangmi.plug.v3') {
sleep(1);
$this->addToQueue($device_id, 'get_power');
}
} elseif (($device_rec['DEVICE_TYPE'] == 'lumi.gateway.v3') || ($device_rec['DEVICE_TYPE'] == 'lumi.acpartner.v3')) {
//
$this->addToQueue($device_id, 'get_prop_fm', '[]');
Expand Down Expand Up @@ -620,7 +626,7 @@ function requestStatus($device_id) {
}
$this->addToQueue($device_id, 'get_prop', '[' . implode(',', $props) . ']');
}

}

/**
Expand Down Expand Up @@ -961,8 +967,19 @@ function propertySetHandle($object, $property, $value) {
} else {
$this->addToQueue($properties[$i]['DEVICE_ID'], 'stop_cf', '[]');
}
} elseif ($properties[$i]['TITLE'] == 'filter1_life') {
// Сброс ресурса фильтра
if ($value == '0' || $value == '') {
$this->addToQueue($properties[$i]['DEVICE_ID'], 'set_f1_hour_used', '[0]');
}
} elseif ($properties[$i]['TITLE'] == 'limit_hum') {
// Установка верхнего предела увлажнения (30, 40, 50, 60, 70, 80)
$value = (int)$value;
if (($value >= 30) && ($value <= 80) && (($value%10) == 0)) {
$this->addToQueue($properties[$i]['DEVICE_ID'], 'set_limit_hum', "[$value]");
}
}

if(($properties[$i]['DEVICE_TYPE'] == 'lumi.gateway.v3') || ($properties[$i]['DEVICE_TYPE'] == 'lumi.acpartner.v3')) {
if ($properties[$i]['TITLE'] == 'current_volume') {
// Изменение громкости
Expand All @@ -983,7 +1000,7 @@ function propertySetHandle($object, $property, $value) {
} else if ($properties[$i]['TITLE'] == 'del_program') {
// Удалить радиостанцию (по ID)
$all_chs = SQLSelectOne("SELECT VALUE FROM miio_commands WHERE DEVICE_ID='" . $properties[$i]['DEVICE_ID'] . "' AND TITLE='all_program'")['VALUE'];
$all_chs = json_decode($all_chs, true);
$all_chs = json_decode($all_chs, true);
foreach($all_chs['chs'] as $ch) {
if ($ch['id'] == $value) {
$ch_url = $ch['url'];
Expand Down Expand Up @@ -1129,13 +1146,15 @@ function processMessage($message, $command, $device_id) {
$res_commands[] = array('command' => $key, 'value' => $value);
$i++;
}
} elseif ($device['DEVICE_TYPE'] == 'philips.light.bulb' && $command == 'get_prop' && is_array($data['result'])) {
$props = explode(',', MIIO_PHILIPS_LIGHT_BULB_PROPS);
$i = 0;
foreach($props as $key) {
$value = $data['result'][$i];
$res_commands[] = array('command' => $key, 'value' => $value);
$i++;
} elseif (($device['DEVICE_TYPE'] == 'philips.light.bulb') || ($device['DEVICE_TYPE'] == 'philips.light.downlight')) {
if ($command == 'get_prop' && is_array($data['result'])) {
$props = explode(',', MIIO_PHILIPS_LIGHT_BULB_PROPS);
$i = 0;
foreach($props as $key) {
$value = $data['result'][$i];
$res_commands[] = array('command' => $key, 'value' => $value);
$i++;
}
}
} elseif ($device['DEVICE_TYPE'] == 'philips.light.candle' && $command == 'get_prop' && is_array($data['result'])) {
$props = explode(',', MIIO_PHILIPS_LIGHT_CANDLE_PROPS);
Expand Down Expand Up @@ -1165,17 +1184,19 @@ function processMessage($message, $command, $device_id) {
$res_commands[] = array('command' => $key, 'value' => $value);
$i++;
}
} elseif ($device['DEVICE_TYPE'] == 'rockrobo.vacuum.v1' && ($command == 'get_status' || $command == 'get_consumable') && is_array($data['result'])) {
foreach($data['result'][0] as $key => $value) {
$res_commands[] = array('command' => $key, 'value' => $value);
if ($key == 'state') {
$state_codes = unserialize (MIIO_MIVACUUM_1_STATE_CODES);
if (array_key_exists($value, $state_codes)) $res_commands[] = array('command' => 'state_text', 'value' => $state_codes[$value]);
} elseif (($device['DEVICE_TYPE'] == 'rockrobo.vacuum.v1') || ($device['DEVICE_TYPE'] == 'roborock.vacuum.s5')) {
if (($command == 'get_status' || $command == 'get_consumable') && is_array($data['result'])) {
foreach($data['result'][0] as $key => $value) {
$res_commands[] = array('command' => $key, 'value' => $value);
if ($key == 'state') {
$state_codes = unserialize (MIIO_MIVACUUM_1_STATE_CODES);
if (array_key_exists($value, $state_codes)) $res_commands[] = array('command' => 'state_text', 'value' => $state_codes[$value]);
}
if ($key == 'error_code') {
$error_codes = unserialize (MIIO_MIVACUUM_1_ERROR_CODES);
if (array_key_exists($value, $error_codes)) $res_commands[] = array('command' => 'error_text', 'value' => $error_codes[$value]);
}
}
if ($key == 'error_code') {
$error_codes = unserialize (MIIO_MIVACUUM_1_ERROR_CODES);
if (array_key_exists($value, $error_codes)) $res_commands[] = array('command' => 'error_text', 'value' => $error_codes[$value]);
}
}
} elseif ($device['DEVICE_TYPE'] == 'chuangmi.plug.m1' && $command == 'get_prop' && is_array($data['result'])) {
$props = explode(',', MIIO_CHUANGMI_PLUG_M1_PROPS);
Expand All @@ -1185,17 +1206,25 @@ function processMessage($message, $command, $device_id) {
$res_commands[] = array('command' => $key, 'value' => $value);
$i++;
}
} elseif ($device['DEVICE_TYPE'] == 'chuangmi.plug.v1' && $command == 'get_prop' && is_array($data['result'])) {
$props = explode(',', MIIO_CHUANGMI_PLUG_V1_PROPS);
$i = 0;
foreach($props as $key) {
$value = $data['result'][$i];
if ($key == 'usb_on') {
if ($value == 'true') $value = 1;
else if ($value == 'false') $value = 0;
} elseif (($device['DEVICE_TYPE'] == 'chuangmi.plug.v1') || ($device['DEVICE_TYPE'] == 'chuangmi.plug.v3')) {
if ($command == 'get_prop' && is_array($data['result'])) {
$props = explode(',', MIIO_CHUANGMI_PLUG_V1_PROPS);
$i = 0;
foreach($props as $key) {
$value = $data['result'][$i];
if ($key == 'usb_on') {
if ($value == 'true') $value = 1;
else if ($value == 'false') $value = 0;
}
$res_commands[] = array('command' => $key, 'value' => $value);
$i++;
}
} elseif ($command == 'get_power') {
$key = 'load_power';
$value = $data['result'][0];
if ($value == '' || $value == 'null' || $value == null) $value = '0';
$value = $value / 100;
$res_commands[] = array('command' => $key, 'value' => $value);
$i++;
}
} elseif ($device['DEVICE_TYPE'] == 'philips.light.ceiling' && $command == 'get_prop' && is_array($data['result'])) {
$props = explode(',', MIIO_PHILIPS_LIGHT_CEILING_PROPS);
Expand Down Expand Up @@ -1223,7 +1252,7 @@ function processMessage($message, $command, $device_id) {
$i = 0;
foreach($props as $key) {
$value = $data['result'][$i];
if ($key == 'flow_params') $key = 'flow';
if ($key == 'flow_params') $key = 'flow';
$res_commands[] = array('command' => $key, 'value' => $value);
$i++;
}
Expand Down Expand Up @@ -1317,7 +1346,7 @@ function processMessage($message, $command, $device_id) {
$res_commands[] = array('command' => $key, 'value' => $value);
}
$res_commands[] = array('command' => 'volume', 'value' => $data['result'][1]);
$res_commands[] = array('command' => 'rel_time', 'value' => $data['result'][2]);
$res_commands[] = array('command' => 'rel_time', 'value' => $data['result'][2]);
}
}

Expand Down
93 changes: 45 additions & 48 deletions templates/xiaomimiio/action_admin.html
Original file line number Diff line number Diff line change
@@ -1,50 +1,7 @@
<!-- action usual -->
[#if DATA_SOURCE="miio_devices" || DATA_SOURCE=""#]
<!-- table miio_devices search -->
[#if VIEW_MODE="search_miio_devices" || VIEW_MODE=""#]

<div class="float-right">
<button class="btn btn-primary btn-sm" data-toggle="modal" data-target="#about"><#LANG_XIMI_APP_ABOUT#>&nbsp;&nbsp;<span class="glyphicon glyphicon-info-sign icon-white"></span>
</button>
</div>

<div class="modal fade" id="about" tabindex="-1" role="dialog" aria-labelledby="about1" aria-hidden="true">
<!-- <div id="about" class="modal hide"> -->
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only"><#LANG_XIMI_APP_CLOSE#></span></button>
<h4 class="modal-title">Xiaomi miIO</h4>
</div>
<div class="modal-body">
<div class="float-right">
<img src="../templates/xiaomimiio/milogo.png" width="48" height="48">
<br><br><p><b>v.1.6b</b></p>
</div>
<p class="float-left">
<#LANG_XIMI_APP_MODULE#><br><br>
<#LANG_XIMI_APP_DISCUS#> <a href="https://majordomo.smartliving.ru/forum/viewtopic.php?f=5&t=4863" target="_blank"><#LANG_XIMI_APP_DISCUS2#></a>.<br>
<#LANG_XIMI_APP_PROJ#> <a href="https://github.com/skysilver-lab/majordomo-xiaomimiio" target="_blank">Github</a>.<br>
<#LANG_XIMI_APP_PROJ#> <a href="https://connect.smartliving.ru/tasks/51.html" target="_blank">Connect</a>.<br>
</p>
<hr size="1">
<p class="float-left">
<#LANG_XIMI_APP_DONATE#>
<ul>
<li>Yandex: <a href="https://money.yandex.ru/to/410011205062626" target="_blank">410011205062626</a></li>
<li>PayPal: <a href="https://www.paypal.me/skysilver" target="_blank">paypal.me/skysilver</a></li>
<li><#LANG_XIMI_APP_DONATE2#><a href="https://connect.smartliving.ru/tasks/51.html" target="_blank">Connect</a></li>
</ul>
</p>
<h6><#LANG_XIMI_APP_THANKS#>: <b>webms</b>, <b>srvsrvsrv</b>, <b>SergeJey</b>, <b>Gelezako</b>, <b>horas</b>, <b>ингвар</b>, <b>Dicont</b>, <b>shawk</b>, <b>ypiter2006</b>, <b>Genplane</b>, <b>TurburatoR</b>, <b>Alex77</b>, <b>iden</b>.</h6>
</div>
<div class="modal-footer">
<div class="pull-left"><#LANG_XIMI_APP_Author#>: <a href="https://telegram.me/agafonov_d" target="_blank">skysilver</a></div>
<button type="button" class="btn btn-default" data-dismiss="modal"><#LANG_XIMI_APP_CLOSE#></button>
</div>
</div>
</div>
</div>
<!-- action usual -->
[#if DATA_SOURCE="miio_devices" || DATA_SOURCE=""#]
<!-- table miio_devices search -->
[#if VIEW_MODE="search_miio_devices" || VIEW_MODE=""#]

<div>
<img src="../templates/xiaomimiio/milogo.png" width="30" height="30">
Expand All @@ -56,6 +13,9 @@ <h6><#LANG_XIMI_APP_THANKS#>: <b>webms</b>, <b>srvsrvsrv</b>, <b>SergeJey</b>, <
[#else#]
<span class="label label-danger" title="Статус цикла"><#LANG_XIMI_APP_CYCLE_STOP#></span>
[#endif#]
<div class="float-right">&nbsp;&nbsp;&nbsp;&nbsp;</div>
<button class="btn btn-primary btn-sm float-right" data-toggle="modal" data-target="#about"><#LANG_XIMI_APP_ABOUT#>&nbsp;&nbsp;<span class="glyphicon glyphicon-info-sign icon-white"></span>
</button>
</div>

<div class="collapse" id='api_settings'>
Expand Down Expand Up @@ -118,7 +78,6 @@ <h6><#LANG_XIMI_APP_THANKS#>: <b>webms</b>, <b>srvsrvsrv</b>, <b>SergeJey</b>, <
[#if VIEW_MODE="edit_miio_devices"#]
[#if ID!=""#]
[#if TITLE!=""#]<h4>[#TITLE#]</h4>[#endif TITLE#]

<ul class="nav nav-tabs">
<li[#if TAB=""#] class="active"[#endif#]>
<a href="?data_source=<#DATA_SOURCE#>&view_mode=<#VIEW_MODE#>&id=<#ID#>&tab="><#LANG_GENERAL#></a>
Expand Down Expand Up @@ -185,3 +144,41 @@ <h6><#LANG_XIMI_APP_THANKS#>: <b>webms</b>, <b>srvsrvsrv</b>, <b>SergeJey</b>, <
[#endif VIEW_MODE#]
<!-- / table miio_commands view -->
[#endif DATA_SOURCE#]

<!-- About -->
<div class="modal fade" id="about" tabindex="-1" role="dialog" aria-labelledby="about1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only"><#LANG_XIMI_APP_CLOSE#></span></button>
<h4 class="modal-title">Xiaomi miIO</h4>
</div>
<div class="modal-body">
<div class="float-right">
<img src="../templates/xiaomimiio/milogo.png" width="48" height="48">
<br><br><p><b>v.1.7b</b></p>
</div>
<p class="float-left">
<#LANG_XIMI_APP_MODULE#><br><br>
<#LANG_XIMI_APP_DISCUS#> <a href="https://majordomo.smartliving.ru/forum/viewtopic.php?f=5&t=4863" target="_blank"><#LANG_XIMI_APP_DISCUS2#></a>.<br>
<#LANG_XIMI_APP_PROJ#> <a href="https://github.com/skysilver-lab/majordomo-xiaomimiio" target="_blank">Github</a>.<br>
<#LANG_XIMI_APP_PROJ#> <a href="https://connect.smartliving.ru/tasks/51.html" target="_blank">Connect</a>.<br>
</p>
<hr size="1">
<p class="float-left">
<#LANG_XIMI_APP_DONATE#>
<ul>
<li>Yandex: <a href="https://money.yandex.ru/to/410011205062626" target="_blank">410011205062626</a></li>
<li>PayPal: <a href="https://www.paypal.me/skysilver" target="_blank">paypal.me/skysilver</a></li>
<li><#LANG_XIMI_APP_DONATE2#><a href="https://connect.smartliving.ru/tasks/51.html" target="_blank">Connect</a></li>
</ul>
</p>
<h6><#LANG_XIMI_APP_THANKS#>: <b>webms</b>, <b>srvsrvsrv</b>, <b>SergeJey</b>, <b>Gelezako</b>, <b>horas</b>, <b>ингвар</b>, <b>Dicont</b>, <b>shawk</b>, <b>ypiter2006</b>, <b>Genplane</b>, <b>TurburatoR</b>, <b>Alex77</b>, <b>iden</b>, <b>TrDA</b>.</h6>
</div>
<div class="modal-footer">
<div class="pull-left"><#LANG_XIMI_APP_Author#>: <a href="https://telegram.me/agafonov_d" target="_blank">skysilver</a></div>
<button type="button" class="btn btn-default" data-dismiss="modal"><#LANG_XIMI_APP_CLOSE#></button>
</div>
</div>
</div>
</div>
Loading

0 comments on commit ee5a5c5

Please sign in to comment.