MiniDevicesTop ИТ блоги 2024-05-05 2024-05-05 Отображаются все разделы
123456

root
0

PHP
Linux Arch
Новые разработки


Без комментариев
Спецификация системного трея для Linux
Трей - специальный способ отображения программ на рабочем столе, когда у программы нет активного видимого окна, и она не отображается в панели задач, но может иметь ограниченный функционал отображения и управления в специальной области рабочего стола.

Чаще всего, от данного механизма требуется всего два действия: позволить приложению отобразить визуальный элемент (иконку или текст) и передать приложению обратный сигнал при совершении какого-либо действия - нажатия, прокрутки, наведения.



Концепция новой спецификации состоит в том, что существуют два вида приложений - которое хочет в трей (далее client), и которое хочет отображать трей (далее host).

Эти приложения должны работать независимо друг от друга, и с как можно меньшим количеством зависимостей в коде. Наиболее простой, надежный, и поддерживаемый большинством языков программирования способ обмена такими примитивными данными - файлы. При чем это могут быть не обязательно файлы блочной файловой системы, это может быть и виртуальная файловая система, к примеру tmpfs.



Опишем краткий способ взаимодействия двух приложений, client и host.



Client.

Приложение, которое хочет отобразиться в трее, должно создать в определенном месте файловой системы, несколько определенных файлов.

Наиболее удобным с точки зрения безопасности и универсальности местом, является /run/user, которое содержит директорию, названную именем UID, в сессию которого произошел вход.

Пункт 1. Создать директорию /run/user/UID/systray/PID, где UID - наш идентификатор пользователя, а PID - идентификатор нашего системного процесса;

Пункт 2. В директории создать несколько файлов с разными предназначениями

a) title - текстовый файл с названием программы

b) tooltip - текстовый файл с текстом всплывающей подсказки при наведении указателя

c) icon_name - текстовый файл с именем иконки из системной темы, которую необходимо отобразить

d) icon_pixbuf - файл текущей иконки в упрощенном формате RGBA с указанием размера иконки

24,24:R,G,B,A,R,G,B,A,R,G,B,A, ... и так 24*24 раз.

e) action - файл обратной связи, который будет использоваться для передачи команды приложению client

f) .updated - обыкновенный пустой файл, время модификации которого будет использовано для обновления данных как приложением client, так и приложением host.

Пункт 3. После исполнения этих действий, приложение должно держать палец на дате изменения файла /run/user/UID/systray/PID/.updated, и если оно изменится - то перечитать файл action - в нем должна быть команда для приложения.

Пункт 4. Опционально приложение может видоизменить иконку или текст, путем обыкновенной перезаписи файлов title, tooltip, icon_name или icon_pixbuf. После окончания записи, должно быть так же изменена дата изменения файла /run/user/UID/systray/PID/.updated - это даст сигнал host-приложению перечитать данные.

Пункт 5. При изменении даты изменения файла /run/user/UID/systray/PID/.updated - приложение может прочитать файл /run/user/UID/systray/PID/action, и реагировать в зависимости от содержимого данного файла. На данный момент поддерживается два вида событий

Activate - равнозначно основному нажатию на иконку приложения. Чаще всего оно активирует основное окно программы, хотя все зависит от логики работы

ContextMenu - равнозначно дополнительному нажатию на иконку приложения, чаще всего это правая кнопка мыши. Активирует контекстное меню программы с основными опциями.

Минимальный пример работы приложения-клиента на PHP с использованием библиотеки php-gtk3:


#!/system/php/bin/php
<?php
global $old_mtime, $mtime, $window;

function add_me_to_tray($my_name, $my_icon, $tooltip, $pixbuf=true) {
	global $mtime;
// Если директории в формате /run/user/CURRENT_USER/systray/PID не существует, то создаем ее
	if (!is_dir($_SERVER['XDG_RUNTIME_DIR']."/systray/".getmypid())) {
		mkdir($_SERVER['XDG_RUNTIME_DIR']."/systray/".getmypid(),0700,true);
	}
	if ($pixbuf==true) {
		file_put_contents($_SERVER['XDG_RUNTIME_DIR']."/systray/".getmypid()."/icon_pixbuf", $my_icon);
	} else {
		file_put_contents($_SERVER['XDG_RUNTIME_DIR']."/systray/".getmypid()."/icon_name", $my_icon);
	}
	touch($_SERVER['XDG_RUNTIME_DIR']."/systray/".getmypid()."/.updated");
	file_put_contents($_SERVER['XDG_RUNTIME_DIR']."/systray/".getmypid()."/title", $my_name);
	file_put_contents($_SERVER['XDG_RUNTIME_DIR']."/systray/".getmypid()."/tooltip", $tooltip);
	$mtime = filectime($_SERVER['XDG_RUNTIME_DIR']."/systray/".getmypid()."/.updated");
}

function get_action() {
	if (!is_file($_SERVER['XDG_RUNTIME_DIR']."/systray/".getmypid()."/action")) {return false;}
	$action=file_get_contents($_SERVER['XDG_RUNTIME_DIR']."/systray/".getmypid()."/action");
	return trim($action);
}
function check_for_actions($window)
{
	global $old_mtime, $mtime, $context_menu;
	$old_mtime = $mtime;	
	$mtime = filectime($_SERVER['XDG_RUNTIME_DIR']."/systray/".getmypid()."/.updated");
	if ($mtime!=$old_mtime) { // Если файл изменился - значит произошло событие
		if (get_action()=="Activate") { // И это событие - активация
			// Все последующее - для активации окна на передний план
			$window->set_visible(true);
			$window->show();
			$window->activate_focus();
			$window->present_with_time($time);
			$window->show();
		}
		if (get_action()=="ContextMenu") { // Создаем простейшее контекстное меню. Реализовано в форме окна, поэтому не закрывается по потере фокуса
			$display = new GdkDisplay();
			global $x,$y;
			$x = $display->get_mouse_positionX(); // Возле курсора мыши, само собой
			$y = $display->get_mouse_positionY();
			unset($display);
			$context_menu = new GtkWindow();
			$context_menu->set_type_hint(2);
			$context_menu->set_size_request(200, 200);
			$context_menu->set_decorated(false);
			$vbox = new GtkBox(GtkOrientation::VERTICAL);
			$vbox->set_border_width(0);
			$o_button = GtkButton::new_with_label("Open"); // Менюшка Open будет открывать наше окно
			$o_button->connect("clicked", function() {global $x,$y, $window, $context_menu;$time=time();$window->show();$window->present_with_time($time);$window->activate_focus();$context_menu->destroy();});
			$vbox->add($o_button);
			$o_button->show();
			$button = GtkButton::new_with_label("Close"); // Менюшка Close будет его закрывать.
			$button->connect("clicked", function() {Gtk::main_quit();});
			$vbox->add($button);
			$button->show();
			$context_menu->add($vbox);
			$context_menu->show();
			$vbox->show();
			$context_menu->move($x+22,$y+22); // Не на иконке же рисовать меню - нарисуем чуть правее и ниже
			$context_menu->activate_focus();
		}
	}
	clearstatcache(); // Пых кеширует date modify по умолчанию, надо чистить
}
Gtk::init();
$window = new GtkWindow();
$window->set_size_request(250, 250);
$window->set_title("SystemTrayExaple");
$window->set_decorated(true);
$vbox = new GtkBox(GtkOrientation::VERTICAL);
$vbox->set_border_width(1);
$label = new GtkLabel("Ну типа контент");
$vbox->add($label);
$button = GtkButton::new_with_label("Кнобка !");
$vbox->add($button);
$window->add($vbox);
$window->connect("destroy", function() {
	Gtk::main_quit();
});
$window->show_all();
// Добавляем нашу программку в трей
add_me_to_tray("Test App", "viber", "Test App в трее", false);
// Добавляем таймер для периодического чека
Gtk::timeout_add(150, function () {global $window; check_for_actions($window);return true;});
$window->set_visible(true);
Gtk::main();


Host.

Приложение, которое хочет быть менеджером трея - самостоятельно организовывает процесс определенного места файловой системы. Общий алгоритм действия следующий:

Пункт 1. Приложение с определенной им самим периодичностью (оптимальным временем реакции является 100-250мс), читает все подкаталоги в директории /run/user/UID/systray/ - существующие каталоги, согласно данной спецификации, носят имя с PID client-приложения, которое захотело отобразиться в трее.

Пункт 2. Каждый найденный PID должен проверяться на наличие в системе, чтобы исключить обработку несуществующих программ. Если язык программирования не имеет в себе функций работы с процессами, то самый простой способ определить жив ли процесс - проверить существование директории с именем PID в директории /proc

Пункт 3. Если процесс найден, то проверяем, не изменилось ли время модицикации файла /run/user/UID/systray/.updated с момента предыдущей проверки. Если оно изменилось, значит приложение client обновило информацию, или же это новое приложение, что в идеале не имеет значения.

Пункт 4. Перечитываем информацию, поданную процессом PID, а именно файлы title, tooltip, icon_name и icon_pixbuf, если они существуют. На основании этой информации, отрисовываем элемент трея в произвольной форме. Чаще всего это иконка со всплывающей подсказкой, к которой привязана обработка нажатий указателя.

Пункт 5. Если PID не найден в системе, это значит что приложения добавившего себя в трей больше не существует, и его нужно удалить из трея и из области файловой системы. Упрощенно говоря командой rm -rf /run/user/UID/systray/PID

Пункт 6. При нажатии на иконку основным или дополнительным нажатием, host должен записать в соответствующий файл /run/user/UID/systray/PID/action действие Activate или ContextMenu, после чего обновить время изменения файла /run/user/UID/systray/.updated, чтобы client увидел что состояние изменилось, прочитал action и отреагировал на запрос.



Минимальный пример работы приложения-хоста на PHP с использованием библиотеки php-gtk3:


<?php
global $tray_box, $old_time, $mtime;
function rmrf($dir) {
   $files = array_diff(scandir($dir), array('.','..'));
    foreach ($files as $file) {
      (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
    }
    return rmdir($dir);
  }
function check_tray()
{
global $tray_box, $old_time, $mtime, $item_button;
// Сперва получаем список всех директорий, и определяем какая из них отсутствует в /proc, чтобы прибить трей
$scan = scandir($_SERVER['XDG_RUNTIME_DIR']."/systray/");
	foreach ($scan as $process) {
		if (is_numeric($process)) {
			if (is_dir("/proc/$process")) { // Процесс все еще существует, можем смотреть, было ли изменено состояние
			$old_mtime[$process] = $mtime[$process];
			$mtime[$process] = filectime($_SERVER['XDG_RUNTIME_DIR']."/systray/".$process."/.updated");	
			if ($mtime[$process]!=$old_mtime[$process]) { // И только если наше гостевое приложение обновило свои данные в системном трее - тогда обновляем и мы
				if (is_file($_SERVER['XDG_RUNTIME_DIR']."/systray/".$process."/icon_name")) {$icon = file_get_contents($_SERVER['XDG_RUNTIME_DIR']."/systray/".$process."/icon_name");}
				if (is_file($_SERVER['XDG_RUNTIME_DIR']."/systray/".$process."/title")) {$title = file_get_contents($_SERVER['XDG_RUNTIME_DIR']."/systray/".$process."/title");}
				if (is_file($_SERVER['XDG_RUNTIME_DIR']."/systray/".$process."/tooltip")) {$tooltip = file_get_contents($_SERVER['XDG_RUNTIME_DIR']."/systray/".$process."/tooltip");}
				if (!isset($item_button[$process])) { // Если процесс новенький, то создаем под него кнопку
					$item_button[$process] = new GtkButton();
					$item_button[$process]->connect("button-press-event",function($button, $event) {process_click($button, $event);});
				} else { // Если процесс уже есть в трее, то удаляем внутренности кнопки, оставляя все остальное. GObject не умеет в удаление событий, а это уменьшит утечку памяти
					foreach ($item_button[$process]->get_children() as &$value) {
						$value->destroy();
					}	
				}
				$item_box[$process] = new GtkBox(GtkOrientation::HORIZONTAL);
				$image = GtkImage::new_from_icon_name("$icon", 5);
				$image->set_pixel_size(22);
				$item_box[$process]->add($image);
				$image->show();
				$item_button[$process]->add($item_box[$process]);
				$item_button[$process]->set_name($process);
				$item_button[$process]->set_relief(GtkReliefStyle::NONE);
				$item_button[$process]->set_has_tooltip(true);
				$item_button[$process]->set_tooltip_text($tooltip);
				$tray_box->add($item_button[$process]);
				$item_box[$process]->show();
				$item_button[$process]->show();
				$tray_box->show();
			}
			} else { // Процесс более не найден - прибиваем его
			rmrf($_SERVER['XDG_RUNTIME_DIR']."/systray/".$process);
			$item_button[$process]->destroy();
			}	
		}
	}	
}
function process_click($item, $event) {
	$process = $item->get_name();
	if ($event->button->button == 1) {file_put_contents($_SERVER['XDG_RUNTIME_DIR']."/systray/".$process."/action", "Activate");} // Нажали левую кнопку - записали Activate
	if ($event->button->button == 3) {file_put_contents($_SERVER['XDG_RUNTIME_DIR']."/systray/".$process."/action", "ContextMenu");} // Нажали правую - записали ContextMenu
	touch($_SERVER['XDG_RUNTIME_DIR']."/systray/".$process."/.updated");
	return false;
}
Gtk::init();
function GtkWindowDestroy($widget=NULL, $event=NULL)
{
	Gtk::main_quit();
}
if (!is_dir($_SERVER['XDG_RUNTIME_DIR']."/systray")) {mkdir($_SERVER['XDG_RUNTIME_DIR']."/systray",0700);} // Если мы запустились первыми в системе, и директории нет - создаем
$win = new GtkWindow();
$win->set_default_size(300, 200);
$win->connect("destroy", "GtkWindowDestroy");
$tray_box = new GtkBox(GtkOrientation::HORIZONTAL);
$win->add($tray_box);
$win->show_all();
Gtk::timeout_add(150, function () {check_tray();return true;}); // Держим палец на трее каждые 150 мс, используя ГыТыКа таймаут. Без паники, процессорное время тратится разве что на ls и stat.
Gtk::main();

Послесловие.


В чем преимущество этой спецификации по сравнению с уже существующими реализациями xembed и SNI (dbus)?


1. Простота использования и наглядная понятность принципа работы;
2. Возможность использования любого ЯП, как для клиента так и для хоста, потому что нет необходимости использовать сторонние технологии
и библиотеки, а библиотеки для работы с файлами есть практически в каждом языке;
3. Нет привязки к графическому серверу. Как хост, так и клиент могут работать с Xorg, Wayland, Framebuffer и с любой существующей и
потенциальной реализацией графики;
4. Возможность безболезненно дополнять функционал;
5. Возможность существования нескольких хостов в рамках одной сессии.


root
5

Умный дом
PHP
Raspberry Pi
Сделай сам


1 комментариев
Как сделать равные задержки в коде на PHP
Оговорюсь сразу, в основном это касается системного программирования на PHP, которое хоть и сложно, но возможно. То есть речь не о Web.



Представьте себе ситуацию, когда у вас бесконечно работает PHP-скрипт, который в определенные промежутки времени должен делать определенное действие, к примеру выборку, неважно откуда - от датчика, с удаленного сайта, и тд. Важно одно - равные промежутки времени.



Вот например как мы сделаем упрощенный счетчик электричества. Раз в секунду будем дергать датчик потребления тока, наберем 3600 значений (столько секунд в часе), потом посчитаем среднее арифметическое, и получим сколько киловатт в час мы потребили. Казалось бы, ничего сложного - считали, записали, секунду подождали, и так до бесконечности.


<?php
$i=0;
$c=0;
while (1==1) {
$c=$c+get_value();
$i++;
if ($i==3600) {$kwh=$c/3600;echo "$kwh час потреблено";$i=0;$c=0;}
usleep(1000000);
}
?>

На первый взгляд этот простой код, каждый час будет выводить среднее арифметическое того, что мы получали в течение часа функцией get_value(). 


Но на самом деле, это будет не так. Эта самая функция будет наверняка дергать какой-то физический порт, ответ с которого может приходить с разной скоростью, равно как время потребует вывод команды echo. Конечно, это будут миллисекунды, но общий смысл в том, что пауза при каждой итерации будет не 1с, а к примеру 1.03с, в следующий раз 1.1 с, а иногда и вовсе 1с как и планировалось. Вроде бы мелочи, но погрешность в расчете электричества в пределах 30 дней, будет составлять десятки гривен. И это только самый простой пример, как неравномерная секунда может сыграть злую шутку с кошельком.



Самый простой способ который пришел мне в голову дабы сделать промежуток между итерациями практически равным секунде - просто замерять время выполнения скрипта от начала блока, до собственно самой функции паузы, и расчитывать значение паузы опираясь на уже затраченное время. 



К примеру, если функция get_value() получила значение с порта за 300мс, то функция sleep должна ожидать уже не 1000мс, а 700мс.



Тогда наш код превращается в такой:

<?php
$i=0;
$c=0;
while (1==1) {
$start_time=microtime(true);
$c=$c+get_value();
$i++;
if ($i==3600) {$kwh=$c/3600;echo "$kwh час потреблено";$i=0;$c=0;}
$gone_time=round(microtime(true)-$start_time,3);
$delay=(1.00-$gone_time)*1000000;
if ($delay<0) {$delay=0;}
usleep($delay);

}

?>

Не правда ли изящно-костыльное решение ?

root
1

Умный дом
Tweaks


Без комментариев
Переход на электроотопление для частного дома

Задумал я перейти на электроотопление.


У меня частный дом. Газ я не проводил принципиально, все на электричестве. По договору мощность 2 кВт, на момент проведения электричества были причины поставить именно эту мощность. Хотя автомат стоит на 16А, а это целых 3.5 кВт, а если по тепловой нагрузке, то вообще выдерживает до 4.2 кВт. 


Это мало. И дорого. Если с нагрузкой я более менее решил, сделав автоматический отсекатель наиболее жирных потребителей вроде бойлера и конвектора, то оплата по тарифу никуда не ушла, что есть печально.


Минутка математики:

Мой физический лимит потребления - примерно 4 кВт. Значит сугубо физически в сутки я могу потребить 96 кВт/ч, из которых 32 кВт/ч будут считаться по ночному тарифу, а оставшиеся 64 кВт/ч по дневному. Следовательно в конце месяца я намотаю 960 кВт электроэнергии по ночному тарифу, и 1920 кВт по дневному. Стоимость электроэнергии на ноябрь 2018 составляет 90 копеек за первые 100 киловатт, 1.68 грн за последущие киловатты. Соответственно при ночном тарифе эта сумма делится на два. Выходит ночью я намотаю 45 грн + 722 грн = 768 грн ну и днем, 90 грн + 3057 грн = 3147 грн, итого 3826 гривен в месяц.


"Электроотопление" в договоре оставляет те же самые расценки, и ту же самую систему рассчитывания, однако предыдущий 100-киловаттный льготный лимит повышается до 3000 кВт. То есть до 3000 кВт тариф 90 копеек, свыше 3000 кВт - 1.68 грн. А это в свою очередь означает, что за месяц я намотаю 435 грн ночью + 1728 грн днем, итого 2163 гривен в месяц. 1663 гривны - экономия. Каждый месяц. А их отопительных, около пяти. Почти 8500 гривен. 


Значит овчинка стоит выделки, поехали ...

По звонку на горячую линию НиколаевОблЭнерго (0800504001) мне попытались дать список документов, которые я должен им сдать: паспорт, код, проектно-техническая документация, планировка дома, тех.условия. На вопрос "что такое тех.условия" девушка ответить не смогла. А мне и правда было интересно, что это такое. Это бумажка ? Справка ? Цифра ? Лицензия ? Ебанный пережиток Совка, с его планами, проектами, справками. Ну почему нельзя по-человечески, зайти в онлайн-кабинет, выбрать меню, нажать кнопку, получить номер счета, оплатить и наслаждаться ? Вечные проверки проверок и справки о том что у тебя есть справка. 

В общем на уточняющий вопрос, девушка из колл-центра дала мне другой номер, 0512-53-90-64, где уже другая девушка, с более опытным голосом рассказала мне, что тех.условия они мне дадут (хотя я так и не понял, что это за предмет такой, тех.условия)


Четверг, 22 ноября, 2018 года.


Общаясь по телефону, я в принципе понял что это за организация, проходил там разок мимо за компанию. Вся организация состоит из одного мужичка в возрасте, хотя и вполне себе адекватного и с отличнейшей памятью, поскольку он вспомнил обстоятельства моего прошлого визита.

Если вкратце, то цена вопроса оказалась 1700 гривен, а с меня требовалась копия договора, планировка дома, техпаспорт на мое устройство обогрева и тип счетчика.

С договором все понятно.

Планировка дома у меня вызвала опасения, поскольку официальный план существует только на старый дом, находящийся в полуразрушенном состоянии, а на актуальный дом плана пока нет. Опасения мои были развеяны этим специалистом. План дома требуется актуальный фактический, его можно начертить в общих чертах от руки, указав количества окон, дверей, местоположение распределительного щитка, и желаемое расположение обогревателя. В качестве обогревателей были выбраны керамические панели, мощностью по 400 Вт в количестве трех штук, дабы оставаться в лимите 2 кВт, прописанном в договоре. Одну я купил. Вроде греет.

С техпаспортом тоже проблем не возникло. Хотя директор-сотрудник проектной организации и удивился. Но не скажу же я ему, что гоняю четыре киловаттных конвектора с WiFi-подключением по цепочке или в зависимости от свободной нагрузки. Пусть думает что все честно и официально.

С счетчиком вышла заминка, поскольку мой счетчик - самый лучший из доступных в 2015 году, Энергомера CE102M-S7, двухзонный, цифровой, со входами и выходами. Специалист сказал что все это хуйня, и счетчик надо обновлять на какой-то параметризованный, с GSM-модулем, стоимостью в районе 4500 грн, иначе есть риск что проект не утвердят. 

Теперь уже удивился я, и у меня были на это причины: во-первых, у меня есть акт приема и установки, где НиколаевОблЭнерго написано что данный счетчик полностью подходит, установлен корректно, параметризован правильно и все такое; во-вторых, порывшись предварительно в интернете, я не встретил ни одну норму закона по которой меня могут обязать поменять счетчик на какой-то особенный; в-третьих, не один сотрудник проектной организации знает матчасть, и я в упор не понимаю разницу в технологиях для подсчета потребленной электроэнергии. Она не меняется. В счетчике ее нет, и не было, его задача - считать лишь потребленную мощность, умножая ее на коэффициент в зависимости от времени суток, а эти 100 кВт нижнего предела - условны, существуют лишь на бумаге, и считаются при помощи карандаша, вычитанием сотни от общей потребленной мощности. Херня какая-то. Но меня предупредили, и в дальнейшей приватной беседе намекнули что коммерческий директор этого монополиста является по совместительству приближенным к одесской конторе по производству счетчиков. Ясно-понятно в чем дело.

Поскольку свет у меня уже проведен, спешить мне некуда, то я поставил перед собой задачу, принципиально не покупать никаких счетчиков. Полезут на рожон - получат иск в суд, жалобу в НКРЕУ и заявление в прокуратуру, ибо повторюсь, на сегодняшний день не существует ни одной нормы закона, обязывающей потребителя менять счетчик за свой счет, при переходе на льготные тарифы.

Проект обещается быть готовым на завтра. Хотя завтра пятница, и я не думаю что это хорошая идея идти беспокоить облЭнерго в преддверии выходного дня. Пойду в понедельник.


Пятница, 23 ноября, 2018 года.


Проект нарисовали. Как я и предполагал, все так пафосно. Пятистраничный документ, основная цель которого - создать лишнюю работу. Целый лист потрачен на то, чтобы описать, что я якобы прошу официально подготовить проект подключения. Чтобы вы понимали как это смешно звучит, представьте что вы идете за хлебом, а вам после хлеба вместе с чеком суют бумажку, где написано что Иванов дал продавщице задание продать хлеб такой-то марки с такой-то полки. Как будто блять, это и так неясно. Куча надписей "подготовил", "проверил", "утвердил", "подписал". Зачеееем ?! Сука, я хочу воткнуть три конвектора в розетку! Какие нах планы, сертификаты, проекты ?!

Мужик что делал проект, так же похвастался что ездил в НиколаевОблЭнерго, рассказал там обо мне как о "принципиальном", и ему сказали нечто вроде "ну ну, пусть попробует". Так что сдается мне, что он тоже получает свой откат за вклад за принуждение к покупке счетчика у правильной компании.



Понедельник, 26 ноября, 2018 года.


Проект приняли без сопротивлений в НиколаевОблЭнерго. Правда никакой бумажки не дали. Сказали ждать звонка. Жду.


Понедельник, 3 декабря, 2018 года.


Проект подтвердили. Я даже удивился, думал будет война и суды, но все обошлось. В возможную защиту НиколаевОблЭнерго хочу сказать, что 29 ноября (спустя 4 дня после подачи заявления) мне был совершен звонок, который я не успел принять. Это могло быть уведомление, что проект утвержден.

Так или иначе, теперь запасусь материалами, и буду монтировать все то, что написал проектировщик в своем проекте.






Боже, сколько пафоса, чтобы подключить три 400-ваттных обогревателя.


Понедельник, 10 декабря, 2018 года.


Инженер в проектной организации зачем-то нарисовал подключение каждого обогревателя через автомат 4А. Не знаю, зачем. Не знаю как это поможет и от чего спасет (напомню, обогреватели формально по 395 Вт). Но суть в том, что штука это жутко не популярная. В наличии в городе я их не нашел. Пришлось заказывать. Должны приехать завтра, во вторник.

Как понимаю, написано это было специально чтобы усложнить процесс, и дать инженерам с облэнерго лишний повод "не принять", мотивируя это не соответствием с проектом.



Понедельник, 17 декабря, 2018 года.


Не имея необходимых навыков и инструментов, монтаж проводки - задача не из простых. Не хватает элементарных практических знаний, скорее относящихся к нюансам, чем собственно к энергетике. Ну например столкнулся с проблемой, что толстый трехжильный плоский кабель, плохо сгибается под углом 90 градусов. Представьте себе горизонтально проложенный плоский кабель, который вдруг понадобилось завернуть вниз или вверх. У вас не получится его просто согнуть, как обычный круглый провод. Это будет либо изгиб с петлей, или изгиб без петли, но достаточно большого радиуса.

В общем закончил.





Позвонил в НиколаевОблЭнерго, спросил куда дальше. 

Сказали вызвать контролера, а сделать это можно в канцелярии в 108 кабинете. Поехал в канцелярию. Там как всегда бардак.

Подошла моя очередь. Пожилая климактеричная тетка стала допытываться что мне нужно. Я ей еле объяснил. Дала заполнить бланк заявления на изменение условий договора (хотя нахуя, если по телефону сказали просто вызвать контролера). Окей, заполнил, сдал. Поинтересовался сколько времени это обычно занимает. Ответила "около месяца, ждите". Охуеть, жду.


Вторник, 18 декабря, 2018 года.


Получил звонок с ОблЭнерго. Сказали приехать подписать договор на вызов контролера. Блядь, я же вчера был в том же месте, неужели нельзя было сразу сказать ?! 

В этот раз выпытал в деталях, что и в какое окошко по какому адресу нести.


Среда, 19 декабря, 2018 года.


Поехал на Чигрина 94а в первое окошко брать квитанцию. Окошко оказалось окошком приема электронной очереди и оказалось закрытым. Класс. Звоню по тому же номеру с которого звонили, поднимает трубку женщина. Спрашиваю в какое окошко идти, если первое закрыто. Получил ответ "идите в первое". И вправду, подхожу и вижу что женщина сидящая в нем, разговаривает со мной по телефону.

Эта оказалась более менее. Видать с личной жизнью все в порядке.

Подписали очередную бумажку-договор на вызов контролера, после чего мне в руки была выдана квитанция на сумму 160 грн 55 коп, которую конечно же в ближайшем радиусе оплатить было негде, поэтому пришлось снова ехать в ближайшее отделение Рошен ПриватБанка на Садовой. Оплатил. Приехал сдал.

Договорился на завтра. Жду.


Четверг, 20 декабря, 2018 года.


Позвонил парень, сказал в течение часа будет. Не обманул. Оказался вполне адекватным парнем с задатками юмора. Такое впечатление что всех адекватных людей в ОблЭнерго, в наказание ссылают на работы контролерами и монтажниками.

Парень сделал несколько замеров, переписал заново данные счетчика, зачем-то поменял входной автомат, пофотографировал все, включая счетчик, установки, автоматы на 4А, электрообогреватель. Спросил что еще в доме имеется: бойлер, стиральная машинка и тд. В общем информацию которая никому нахер не надо.

Выписал акт. Попрощался и порекомендовал периодически прозванивать на 0-800, интересоваться поменяли ли тариф. Вроде как финальная стадия, фух...


Понедельник, 14 января, 2019 года.


В очередной раз позвонив на горячую линию НиколаевОблЭнерго, выяснил хорошую новость. Тариф активирован с 1 декабря 2019 года. Ура. Провода, автоматы и прочие потемкинские деревни можно смело откручивать :)


Сразу же рад предоставить РЕАЛЬНУЮ цифру экономии за декабрь. Без расчетов, фотошопов, анализов, прогнозов и прочей теории. Только практика.



Итак, за НЕ САМЫЙ ХОЛОДНЫЙ месяц декабрь, по старому обычному тарифу было уплачено 2030 гривен. 

Поскольку тариф был введен задним числом уже после оплаты - был сделан перерасчет по этому новому тарифу. Экономия как вы видите, составила 1158 гривен.


Подытожим сколько чего было потрачено:


Денег

1. Создание проекта на электроотопление в проектной организации - 1700 грн.

2. Покупка необходимого метража провода, указанного в проекте - 400 грн. Он остается у меня.

3. Покупка трех автоматов, указанных в проекте - 180 грн. Они тоже остаются.

4. Вызов инженера для фактической проверки - 160 грн.


Времени

1. 1 день на проект.

2. 7 дней на согласование проекта в НиколаевОблЭнерго.

3. 14 дней на монтирование всего нарисованного в проекте своими силами, включая время на покупку материала и ожидание его доставки.

4. 3 дня на вызов инженера и его приезд.

5. 24 дня в среднем, на изменение счета в недрах НиколаевОблЭнерго.


Итого, за 2440 гривен (из которых 580 остались в доме в виду оборудования) и 1 месяц 19 дней (что может быть сокращено до 1 месяца при наличии знакомого электрика) я получил относительно большую экономию. Всего лишь за один не холодный месяц отопительного сезона, окупилась половина (!) всех затрат.



КОРОЧЕ, РЕКОМЕНДУЮ!


root
2

Linux Arch
Windows 7
Windows 10
Tweaks


1 комментариев
Если ОС долго загружается

Долгое время ломал голову над интересным фактом:

Имеется вполне современный даже по сегодняшним меркам компьютер: 2-ядерный Core i3, 16 Gb DDR4, NVME-накопитель со скоростью чтения 2.4 Гб\с.

Но парадокс, система грузится долго. И Linux и Windows 7. С очень и очень странными симптомами: долгой начальной инициализацией.


Методом проб, ошибок, подстановок, нашел корень проблемы: UEFI. Точнее режим совместимости с Legacy и разметка NVMe-накопителя в MBR, а не GPT. Видимо системе требуется огромное время на переходы с одного режима в другой, а потом обратно + ядро системы пытается определить список оборудования самостоятельно вместо того чтобы просто получить его с EFI\ACPI.


Итак, если у вас вроде как современный компьютер, и вы чувствуете что ОС может загружаться быстрее, чем загружается - отключите в CMOS (Setup) все совместимости со старым режимом (Legacy, CSM и тд), оставив лишь UEFI, и будьте готовы полностью переразметить ваш NVMe (а может и SATA SSD) из старого режима MBR в новый GPT. Разумеется все системы придется переустановить заново, в режиме UEFI.


У меня это дало прирост загрузки с 20-30 сек с момента нажатия кнопки, до 3-5 секунд до появления рабочего стола. Новое оборудование должно работать в новом режиме. 


root
1

Linux CentOS
Linux Debian
Сетевое железо
Mikrotik
Домашний хостинг


Без комментариев
Почему сетевой кабель имеет значение

Относительно долгое время мой домашний сервер мучала одна интересная проблема. Периодически уходил в оффлайн. Подключиться невозможно.

Долгое время грешил на терморежим. Поставил вентилятор (там было пассивное охлаждение). Проблема не решилась. Поставил другие системы (метался между Дебианом, Убунтой и Центосью) - то же самое.

Решил обвинить материнскую плату и железо.

Написал скрипт который следит за состоянием сервера изнутри, образно говоря, каждую минуту пишет запись в лог. И о чудо, когда сервер "висит" - на самом деле он не висит, а работает. В чем я убедился когда подключил дисплей.


Стал грешить на сетевую подсистему. И правда. В логах нашел такое:


[  304.008655] r8169 0000:02:00.0 enp2s0: link down
[  307.056987] r8169 0000:02:00.0 enp2s0: link up
[  318.711223] r8169 0000:02:00.0 enp2s0: link down
[  321.433996] r8169 0000:02:00.0 enp2s0: link up
[  330.291883] r8169 0000:02:00.0 enp2s0: link down
[  333.198115] r8169 0000:02:00.0 enp2s0: link up
[  334.441311] r8169 0000:02:00.0 enp2s0: link down
[  337.207600] r8169 0000:02:00.0 enp2s0: link up
[  338.095204] r8169 0000:02:00.0 enp2s0: link down
[  341.248507] r8169 0000:02:00.0 enp2s0: link up
[  356.632769] r8169 0000:02:00.0 enp2s0: link down
[  359.651745] r8169 0000:02:00.0 enp2s0: link up
[  687.127200] r8169 0000:02:00.0 enp2s0: link down
[  690.253646] r8169 0000:02:00.0 enp2s0: link up
[  694.503367] r8169 0000:02:00.0 enp2s0: link down
[  697.181026] r8169 0000:02:00.0 enp2s0: link up
[  703.279311] r8169 0000:02:00.0 enp2s0: link down
Каждые несколько секунд сеть отключалась и подключалась. Само собой перво-наперво я подумал на роутер. Хоть и Mikrotik, но тем не менее достаточно старенький.

Конечно это было бы странно, учитывая что другие устройства прекрасно с ним работали, но тем не менее роутер я поменял на вкусненький, гигабитненький, с 5-тигигагерцовым WiFi.

Проблема осталась.

Пришла очередь сетевой карты. Ее конечно я менять не стал (да и не смог бы, у меня все на MiniITX), однако на плате их две, и я попробовал другую с предсказуемым результатом: не поменялось ровным счетом НИЧЕГО. Вдобавок обнаружил интересную особенность: если достать-вставить кабель - сеть появляется, т.е. сервер перезагружать уже не нужно. Ну думаю, ладно, придется брать в руки паяльник и паять костыль на Arduine который будет перетыкивать этот сетевой кабель.


И тут меня дернул черт попробовать другой кабель.

Все заработало. Сбоев нет. Интерфейс работает. Ничего не переподключается.


И я реально НЕ ПОНИМАЮ в чем проблема. Этот "нерабочий" патчкорд отлично прозванивается тестером. Работает на других системах. Он не работает только на этом сервере. Чудеса.


Мораль сего поста такова: если у вас стало слишком часто пропадать соединение - не спешите покупать новый роутер или переустанавливать систему. Просто попробуйте другой сетевой кабель.


P.S. этот сайт хостится именно на этом сервере.

Посмотрите так же: Переход на электроотопление для частного дома _ и Vastking M910A firmware _


Вы должны войти в систему, чтобы создавать блоги

35-3 / 26-9
В этой строке мы предупреждаем Вас, что можем использовать так называемые cookies
Нам искренне плевать на введенную Вами информацию о себе. Мы просто запоминаем у Вас на устройстве то, что Вы же и настроили.