tig — улучшаем продуктивность работы с git |
Всем привет,
хочу рассказать о консольной утилите, которая значительно увеличила мою продуктивность работы с Git, и, надеюсь, ускорит и вашу также. Называется она tig и была написана канадским программистом Джонасом Фонсека (Jonas Fonseca) ещё в далёком 2006-м году, но по настоящий день она активно развивается и поддерживается в великолепном состоянии. Я хочу показать её функционал (внимание, есть относительно тяжелые gif-ки внутри) и поделиться самыми удобными способами использования.
Несмотря на обилие визуальных GUI для работы с git, многие разработчики всё же предпочитают работать в консоли. В git есть много средств для увеличения производительности — алиасы, автодополнение, автоматическая коррекция ошибок и т.д., но всё же многие рядовые действия, такие как навигация по истории коммитов, анализ diff-ов, просмотр git blame и прочее — отнимают прилично времени и не всегда удобны.
Установка подробно описана в документации на главной странице проекта.
Если вы работаете в MacOS, то tig
доступен через Homebrew:
brew install tig
В Linux она тоже доступна для всех основных репозиториев:
apt-get install tig
yum install tig
Для остальных вариантов, стандартная схема — скачать исходный код (из релизов или через git clone
и выполнить make && make install
. Это подробно описано в ссылке выше.
Вот коротенькое демо того, как выглядит интерфейс при запуске команды tig
из директории репозитория:
В целом, как и следует ожидает от графического (пусть и текстового) интерфейса, но использование программы достаточно интуитивное, но всё же для начала нужно узнать несколько базовых сочетаний клавиш, на которых вся работа с программой и строится.
Главная клавиша это — h
: показать окно помощи :)
Как видим, есть несколько режимов (views) — главный, режим просмотра diff-ов, режим лога, режим просмотра дерева файлов, blame режим, просмотр текущего статуса и т.д.
Между всеми этими режимами переключаться довольно просто, обычно достаточно стрелочками (или j
/k
) выбрать нужную запись в логе или файл и нажать Enter
, либо, как, например, в случае с blame
— соответствующую клавишу (b
).
Режимы отображаются либо на весь экран либо в dual-split режиме. Последний бывает либо горизонтальный, либо вертикальный — программа сама выбрает его в зависимости от соотношения сторон терминала, и умеет обновлять на лету. Чтобы закрыть текущий режим (и вернуться к предыдущему) — просто нажимаем q
(quit). Чтобы, наоборот, развернуть окно с текущим режимом на полный экран — O
. Переключаться между режимами в dual-split режиме — Tab
.
В режиме просмотра diff
очень удобно увеличивать количество строк сверху и снизу изменённой строки с помощью [
и ]
(уменьшить и увеличить, соответственно):
Также в программе есть функция поиска по файлам (g
— grep
), поиска в окне (/
), открытия файла во внешнем редакторе (e
) и, в целом, интерфейс будет особенно комфортен тем, кто знаком с vim
. Например, с помощью :
можно вводить различные команды, переходить к нужной строке и т.д.
Для некоторых команд tig
может спокойно работать как drop-in замена git
.
tig status
tig log
tig show
tig blame file
tig grep pattern
tig refs
tig stash
tig status
Также, в режиме pager-а:
git show | tig
tig
достаточно гибкий в плане настройки — у него есть файл конфигурации (путь к которому также можно конфигурировать через TIGRC_USER) — ~/.tigrc
и поддержка readline.
Можно создавать свои собственные команды. Например, следующая команда копирует ID коммита в буфер обмена на MacOS X:
bind generic 5 !@sh -c "echo %(commit) | pbcopy"
У проекта отличная документация, больше о расширении функционала можно прочесть в ней.
tig
это одна из тех утилит, которые ускорили мою продуктивность ежедневной работы с git очень значительно. Не переключаясь между окнами, из терминала вы получаете очень удобный и интуитивный интерфейс для быстрой навигации по истории и изменениям вашего git-репозитория.
Программа написана на C и работает чудовищно быстро, что всегда приятно, особенно на больших репозиториях.
Метки: author imrobot2002 системы управления версиями git tig ui |
tig — улучшаем продуктивность работы с git |
Всем привет,
хочу рассказать о консольной утилите, которая значительно увеличила мою продуктивность работы с Git, и, надеюсь, ускорит и вашу также. Называется она tig и была написана канадским программистом Джонасом Фонсека (Jonas Fonseca) ещё в далёком 2006-м году, но по настоящий день она активно развивается и поддерживается в великолепном состоянии. Я хочу показать её функционал (внимание, есть относительно тяжелые gif-ки внутри) и поделиться самыми удобными способами использования.
Несмотря на обилие визуальных GUI для работы с git, многие разработчики всё же предпочитают работать в консоли. В git есть много средств для увеличения производительности — алиасы, автодополнение, автоматическая коррекция ошибок и т.д., но всё же многие рядовые действия, такие как навигация по истории коммитов, анализ diff-ов, просмотр git blame и прочее — отнимают прилично времени и не всегда удобны.
Установка подробно описана в документации на главной странице проекта.
Если вы работаете в MacOS, то tig
доступен через Homebrew:
brew install tig
В Linux она тоже доступна для всех основных репозиториев:
apt-get install tig
yum install tig
Для остальных вариантов, стандартная схема — скачать исходный код (из релизов или через git clone
и выполнить make && make install
. Это подробно описано в ссылке выше.
Вот коротенькое демо того, как выглядит интерфейс при запуске команды tig
из директории репозитория:
В целом, как и следует ожидает от графического (пусть и текстового) интерфейса, но использование программы достаточно интуитивное, но всё же для начала нужно узнать несколько базовых сочетаний клавиш, на которых вся работа с программой и строится.
Главная клавиша это — h
: показать окно помощи :)
Как видим, есть несколько режимов (views) — главный, режим просмотра diff-ов, режим лога, режим просмотра дерева файлов, blame режим, просмотр текущего статуса и т.д.
Между всеми этими режимами переключаться довольно просто, обычно достаточно стрелочками (или j
/k
) выбрать нужную запись в логе или файл и нажать Enter
, либо, как, например, в случае с blame
— соответствующую клавишу (b
).
Режимы отображаются либо на весь экран либо в dual-split режиме. Последний бывает либо горизонтальный, либо вертикальный — программа сама выбрает его в зависимости от соотношения сторон терминала, и умеет обновлять на лету. Чтобы закрыть текущий режим (и вернуться к предыдущему) — просто нажимаем q
(quit). Чтобы, наоборот, развернуть окно с текущим режимом на полный экран — O
. Переключаться между режимами в dual-split режиме — Tab
.
В режиме просмотра diff
очень удобно увеличивать количество строк сверху и снизу изменённой строки с помощью [
и ]
(уменьшить и увеличить, соответственно):
Также в программе есть функция поиска по файлам (g
— grep
), поиска в окне (/
), открытия файла во внешнем редакторе (e
) и, в целом, интерфейс будет особенно комфортен тем, кто знаком с vim
. Например, с помощью :
можно вводить различные команды, переходить к нужной строке и т.д.
Для некоторых команд tig
может спокойно работать как drop-in замена git
.
tig status
tig log
tig show
tig blame file
tig grep pattern
tig refs
tig stash
tig status
Также, в режиме pager-а:
git show | tig
tig
достаточно гибкий в плане настройки — у него есть файл конфигурации (путь к которому также можно конфигурировать через TIGRC_USER) — ~/.tigrc
и поддержка readline.
Можно создавать свои собственные команды. Например, следующая команда копирует ID коммита в буфер обмена на MacOS X:
bind generic 5 !@sh -c "echo %(commit) | pbcopy"
У проекта отличная документация, больше о расширении функционала можно прочесть в ней.
tig
это одна из тех утилит, которые ускорили мою продуктивность ежедневной работы с git очень значительно. Не переключаясь между окнами, из терминала вы получаете очень удобный и интуитивный интерфейс для быстрой навигации по истории и изменениям вашего git-репозитория.
Программа написана на C и работает чудовищно быстро, что всегда приятно, особенно на больших репозиториях.
Метки: author imrobot2002 системы управления версиями git tig ui |
tig — улучшаем продуктивность работы с git |
Всем привет,
хочу рассказать о консольной утилите, которая значительно увеличила мою продуктивность работы с Git, и, надеюсь, ускорит и вашу также. Называется она tig и была написана канадским программистом Джонасом Фонсека (Jonas Fonseca) ещё в далёком 2006-м году, но по настоящий день она активно развивается и поддерживается в великолепном состоянии. Я хочу показать её функционал (внимание, есть относительно тяжелые gif-ки внутри) и поделиться самыми удобными способами использования.
Несмотря на обилие визуальных GUI для работы с git, многие разработчики всё же предпочитают работать в консоли. В git есть много средств для увеличения производительности — алиасы, автодополнение, автоматическая коррекция ошибок и т.д., но всё же многие рядовые действия, такие как навигация по истории коммитов, анализ diff-ов, просмотр git blame и прочее — отнимают прилично времени и не всегда удобны.
Установка подробно описана в документации на главной странице проекта.
Если вы работаете в MacOS, то tig
доступен через Homebrew:
brew install tig
В Linux она тоже доступна для всех основных репозиториев:
apt-get install tig
yum install tig
Для остальных вариантов, стандартная схема — скачать исходный код (из релизов или через git clone
и выполнить make && make install
. Это подробно описано в ссылке выше.
Вот коротенькое демо того, как выглядит интерфейс при запуске команды tig
из директории репозитория:
В целом, как и следует ожидает от графического (пусть и текстового) интерфейса, но использование программы достаточно интуитивное, но всё же для начала нужно узнать несколько базовых сочетаний клавиш, на которых вся работа с программой и строится.
Главная клавиша это — h
: показать окно помощи :)
Как видим, есть несколько режимов (views) — главный, режим просмотра diff-ов, режим лога, режим просмотра дерева файлов, blame режим, просмотр текущего статуса и т.д.
Между всеми этими режимами переключаться довольно просто, обычно достаточно стрелочками (или j
/k
) выбрать нужную запись в логе или файл и нажать Enter
, либо, как, например, в случае с blame
— соответствующую клавишу (b
).
Режимы отображаются либо на весь экран либо в dual-split режиме. Последний бывает либо горизонтальный, либо вертикальный — программа сама выбрает его в зависимости от соотношения сторон терминала, и умеет обновлять на лету. Чтобы закрыть текущий режим (и вернуться к предыдущему) — просто нажимаем q
(quit). Чтобы, наоборот, развернуть окно с текущим режимом на полный экран — O
. Переключаться между режимами в dual-split режиме — Tab
.
В режиме просмотра diff
очень удобно увеличивать количество строк сверху и снизу изменённой строки с помощью [
и ]
(уменьшить и увеличить, соответственно):
Также в программе есть функция поиска по файлам (g
— grep
), поиска в окне (/
), открытия файла во внешнем редакторе (e
) и, в целом, интерфейс будет особенно комфортен тем, кто знаком с vim
. Например, с помощью :
можно вводить различные команды, переходить к нужной строке и т.д.
Для некоторых команд tig
может спокойно работать как drop-in замена git
.
tig status
tig log
tig show
tig blame file
tig grep pattern
tig refs
tig stash
tig status
Также, в режиме pager-а:
git show | tig
tig
достаточно гибкий в плане настройки — у него есть файл конфигурации (путь к которому также можно конфигурировать через TIGRC_USER) — ~/.tigrc
и поддержка readline.
Можно создавать свои собственные команды. Например, следующая команда копирует ID коммита в буфер обмена на MacOS X:
bind generic 5 !@sh -c "echo %(commit) | pbcopy"
У проекта отличная документация, больше о расширении функционала можно прочесть в ней.
tig
это одна из тех утилит, которые ускорили мою продуктивность ежедневной работы с git очень значительно. Не переключаясь между окнами, из терминала вы получаете очень удобный и интуитивный интерфейс для быстрой навигации по истории и изменениям вашего git-репозитория.
Программа написана на C и работает чудовищно быстро, что всегда приятно, особенно на больших репозиториях.
Метки: author imrobot2002 системы управления версиями git tig ui |
[Из песочницы] Learnopengl. Урок 2.5 — Источники света |
Метки: author UberSchlag разработка игр программирование c++ перевод glsl opengl opengl 3 light casters shading |
[Из песочницы] Learnopengl. Урок 2.5 — Источники света |
Метки: author UberSchlag разработка игр программирование c++ перевод glsl opengl opengl 3 light casters shading |
[Из песочницы] Learnopengl. Урок 2.5 — Источники света |
Метки: author UberSchlag разработка игр программирование c++ перевод glsl opengl opengl 3 light casters shading |
Кто все эти люди? Давайте спросим К50 |
Метки: author i-cat разработка мобильных приложений разработка веб-сайтов программирование блог компании voximplant calltracking |
Кто все эти люди? Давайте спросим К50 |
Метки: author i-cat разработка мобильных приложений разработка веб-сайтов программирование блог компании voximplant calltracking |
Кто все эти люди? Давайте спросим К50 |
Метки: author i-cat разработка мобильных приложений разработка веб-сайтов программирование блог компании voximplant calltracking |
MBLTdev 2017: первые спикеры, последние билеты по выгодной цене |
|
MBLTdev 2017: первые спикеры, последние билеты по выгодной цене |
|
MBLTdev 2017: первые спикеры, последние билеты по выгодной цене |
|
Инженерные системы наших дата-центров и их мониторинг, часть первая |
Отдельно стоит упомянуть ИБП, они опрашиваются непосредственно SCADA, минуя ПЛК, по SNMP-протоколу.
(* PLC_A2 *)
%QX256.0 := A2_1QF1; //присваиваем каждому биту 256го слова
%QX256.1 := A2_1QF2; //текущее состояние различных автоматов
%QX256.2 := A2_QS1;
%QX256.3 := A2_QS2;
%QX256.4 := A2_3QF1;
%QX256.5 := A2_3QF2;
%QX256.6 := A2_3QF3;
%QX256.7 := A2_3QF4;
%QX256.8 := A2_3QF5;
%QX256.9 := A2_3QF6;
%QX256.10 := A2_3QF7;
%QX256.11 := A2_3QF8;
%QX256.12 := A2_3QF9;
%QX256.13 := A2_3QF10;
%QX256.14 := A2_KM1;
%QX256.15 := A2_KM2;
(* QF1 *) //вводной автоматический выключатель № 1
%QW332 := QF1_I_L1; //токи по фазам
%QW333 := QF1_I_L2;
%QW334 := QF1_I_L3;
%QW335 := QF1_U_L12; //линейные (межфазные) напряжения
%QW336 := QF1_U_L23;
%QW337 := QF1_U_L31;
%QW338 := QF1_U_L1; //фазные (фаза-нуль) напряжения
%QW339 := QF1_U_L2;
%QW340 := QF1_U_L3;
%QW341 := QF1_P_L1; //активная мощность по фазам
%QW342 := QF1_P_L2;
%QW343 := QF1_P_L3;
%QW344 := QF1_P_Sum; //суммарная активная мощность (кВт)
%QW345 := QF1_Q_L1; //реактивная мощность по фазам
%QW346 := QF1_Q_L2;
%QW347 := QF1_Q_L3;
%QW348 := QF1_Q_Sum; //суммарная реактивная мощность (квар)
%QW349 := QF1_S_Sum; //полная мощность (кВА)
%QW350 := QF1_CosF; //коэффициент мощности
//Это работа кодогенератора CODESYS, в котором есть удобный настройщик связи
//с периферией по Modbus TCP/IP. Эта подпрограмма, в частности, отвечает
//за получение от ОВЕН МЭ110-220.3М показаний
//по трем напряжениям фаза-нейтраль
PROGRAM MBCFG_subCMS_1(* generated by config one prg for each slave *)
VAR_OUTPUT
U_L1 : WORD; (**)
U_L2 : WORD; (**)
U_L3 : WORD; (**)
/*--- system variables (read only) ----------------------------------------*/
MBCFG_IpAddress : STRING(12) := 'XXX.XXX.XXX.XXX';//IP-адрес Slave-устройства
MBCFG_Port : UINT := 502; //Порт, дефолтный
MBCFG_UnitID : BYTE := 2; //ID Slave-устройства
MBCFG_TimeOut : TIME := t#300ms; //Таймаут на получение ответа
MBCFG_RequestDelay : TIME := t#1000ms; //Задержка до следующего опроса
MBCFG_Error : MBCFG_eERROR := MBCFG_START_UP;
MBCFG_LastJob : MBCFG_typCOM_JOB;
/*-------------------------------------------------------------------------*/
END_VAR
VAR CONSTANT
zz_VARIABLECOUNT: INT := 3; (* number of variables *)
zz_JOBCOUNT : INT := 1; (* number of jobs *)
END_VAR
VAR
/*=== VARIABLE LIST =============*/
zz_VariableList : ARRAY[1..zz_VARIABLECOUNT] OF MBCFG_typVARIABLE :=
( DataType := MBCFG_TYPE_WORD,
ByteOrder := MBCFG_BYTE_ORDER_0,
BitSize := 16,
ptVar := 0,
ReadJobIndex := 1,
ReadStartBitNo := 0,
WriteJobIndex := 0,
WriteStartBitNo := 0 ),
( DataType := MBCFG_TYPE_WORD,
ByteOrder := MBCFG_BYTE_ORDER_0,
BitSize := 16,
ptVar := 0,
ReadJobIndex := 1,
ReadStartBitNo := 32,
WriteJobIndex := 0,
WriteStartBitNo := 0 ),
( DataType := MBCFG_TYPE_WORD,
ByteOrder := MBCFG_BYTE_ORDER_0,
BitSize := 16,
ptVar := 0,
ReadJobIndex := 1,
ReadStartBitNo := 64,
WriteJobIndex := 0,
WriteStartBitNo := 0
);
/*=== JOB LIST ==================*/
zz_JobList : ARRAY[1..zz_JOBCOUNT] OF MBCFG_typCOM_JOB :=
( Functioncode := 3, //Номер функции, 0x03, Read Holding Registers
ReadStartAddress := 26,//Адрес первого регистра
ReadQuantity := 5, //Кол-во регистров, которые следует прочесть
WriteStartAddress := 0,
WriteQuantity := 0,
ptReadData := 0,
ptWriteData := 0
);
zz_DataField_1_Read : ARRAY[1..5] OF WORD;
/*=== MODBUS MASTER ==============*/
zz_MBCFG_MASTER_ETH : MBCFG_MASTER_TCP;
END_VAR
/*--- for each variable -------------------------*/
zz_VariableList[1].ptVar := ADR(U_L1);
zz_VariableList[2].ptVar := ADR(U_L2);
zz_VariableList[3].ptVar := ADR(U_L3);
/*-----------------------------------------------*/
/*--- for each job -----------------------------------*/
zz_JobList[1].ptReadData := ADR(zz_DataField_1_Read);
/*----------------------------------------------------*/
/*#### START OF FIXED CODE #####################################*/
zz_MBCFG_MASTER_ETH( strIpAddress := MBCFG_IpAddress,
uiPort := MBCFG_Port,
bUnitID := MBCFG_UnitID,
tTimeOut := MBCFG_TimeOut,
iVariableCount := zz_VARIABLECOUNT,
ptVariableList := ADR(zz_VariableList),
iJobCount := zz_JOBCOUNT,
ptJobList := ADR(zz_JobList),
tRequestDelay := MBCFG_RequestDelay,
eError => MBCFG_Error,
LastJob => MBCFG_LastJob
);
%QW377 := U_L1;
%QW378 := U_L2;
%QW379 := U_L3;
Метки: author NobleD5 it- инфраструктура блог компании миран миран цод дата-центр инженерная инфраструктура мониторинг |
Инженерные системы наших дата-центров и их мониторинг, часть первая |
Отдельно стоит упомянуть ИБП, они опрашиваются непосредственно SCADA, минуя ПЛК, по SNMP-протоколу.
(* PLC_A2 *)
%QX256.0 := A2_1QF1; //присваиваем каждому биту 256го слова
%QX256.1 := A2_1QF2; //текущее состояние различных автоматов
%QX256.2 := A2_QS1;
%QX256.3 := A2_QS2;
%QX256.4 := A2_3QF1;
%QX256.5 := A2_3QF2;
%QX256.6 := A2_3QF3;
%QX256.7 := A2_3QF4;
%QX256.8 := A2_3QF5;
%QX256.9 := A2_3QF6;
%QX256.10 := A2_3QF7;
%QX256.11 := A2_3QF8;
%QX256.12 := A2_3QF9;
%QX256.13 := A2_3QF10;
%QX256.14 := A2_KM1;
%QX256.15 := A2_KM2;
(* QF1 *) //вводной автоматический выключатель № 1
%QW332 := QF1_I_L1; //токи по фазам
%QW333 := QF1_I_L2;
%QW334 := QF1_I_L3;
%QW335 := QF1_U_L12; //линейные (межфазные) напряжения
%QW336 := QF1_U_L23;
%QW337 := QF1_U_L31;
%QW338 := QF1_U_L1; //фазные (фаза-нуль) напряжения
%QW339 := QF1_U_L2;
%QW340 := QF1_U_L3;
%QW341 := QF1_P_L1; //активная мощность по фазам
%QW342 := QF1_P_L2;
%QW343 := QF1_P_L3;
%QW344 := QF1_P_Sum; //суммарная активная мощность (кВт)
%QW345 := QF1_Q_L1; //реактивная мощность по фазам
%QW346 := QF1_Q_L2;
%QW347 := QF1_Q_L3;
%QW348 := QF1_Q_Sum; //суммарная реактивная мощность (квар)
%QW349 := QF1_S_Sum; //полная мощность (кВА)
%QW350 := QF1_CosF; //коэффициент мощности
//Это работа кодогенератора CODESYS, в котором есть удобный настройщик связи
//с периферией по Modbus TCP/IP. Эта подпрограмма, в частности, отвечает
//за получение от ОВЕН МЭ110-220.3М показаний
//по трем напряжениям фаза-нейтраль
PROGRAM MBCFG_subCMS_1(* generated by config one prg for each slave *)
VAR_OUTPUT
U_L1 : WORD; (**)
U_L2 : WORD; (**)
U_L3 : WORD; (**)
/*--- system variables (read only) ----------------------------------------*/
MBCFG_IpAddress : STRING(12) := 'XXX.XXX.XXX.XXX';//IP-адрес Slave-устройства
MBCFG_Port : UINT := 502; //Порт, дефолтный
MBCFG_UnitID : BYTE := 2; //ID Slave-устройства
MBCFG_TimeOut : TIME := t#300ms; //Таймаут на получение ответа
MBCFG_RequestDelay : TIME := t#1000ms; //Задержка до следующего опроса
MBCFG_Error : MBCFG_eERROR := MBCFG_START_UP;
MBCFG_LastJob : MBCFG_typCOM_JOB;
/*-------------------------------------------------------------------------*/
END_VAR
VAR CONSTANT
zz_VARIABLECOUNT: INT := 3; (* number of variables *)
zz_JOBCOUNT : INT := 1; (* number of jobs *)
END_VAR
VAR
/*=== VARIABLE LIST =============*/
zz_VariableList : ARRAY[1..zz_VARIABLECOUNT] OF MBCFG_typVARIABLE :=
( DataType := MBCFG_TYPE_WORD,
ByteOrder := MBCFG_BYTE_ORDER_0,
BitSize := 16,
ptVar := 0,
ReadJobIndex := 1,
ReadStartBitNo := 0,
WriteJobIndex := 0,
WriteStartBitNo := 0 ),
( DataType := MBCFG_TYPE_WORD,
ByteOrder := MBCFG_BYTE_ORDER_0,
BitSize := 16,
ptVar := 0,
ReadJobIndex := 1,
ReadStartBitNo := 32,
WriteJobIndex := 0,
WriteStartBitNo := 0 ),
( DataType := MBCFG_TYPE_WORD,
ByteOrder := MBCFG_BYTE_ORDER_0,
BitSize := 16,
ptVar := 0,
ReadJobIndex := 1,
ReadStartBitNo := 64,
WriteJobIndex := 0,
WriteStartBitNo := 0
);
/*=== JOB LIST ==================*/
zz_JobList : ARRAY[1..zz_JOBCOUNT] OF MBCFG_typCOM_JOB :=
( Functioncode := 3, //Номер функции, 0x03, Read Holding Registers
ReadStartAddress := 26,//Адрес первого регистра
ReadQuantity := 5, //Кол-во регистров, которые следует прочесть
WriteStartAddress := 0,
WriteQuantity := 0,
ptReadData := 0,
ptWriteData := 0
);
zz_DataField_1_Read : ARRAY[1..5] OF WORD;
/*=== MODBUS MASTER ==============*/
zz_MBCFG_MASTER_ETH : MBCFG_MASTER_TCP;
END_VAR
/*--- for each variable -------------------------*/
zz_VariableList[1].ptVar := ADR(U_L1);
zz_VariableList[2].ptVar := ADR(U_L2);
zz_VariableList[3].ptVar := ADR(U_L3);
/*-----------------------------------------------*/
/*--- for each job -----------------------------------*/
zz_JobList[1].ptReadData := ADR(zz_DataField_1_Read);
/*----------------------------------------------------*/
/*#### START OF FIXED CODE #####################################*/
zz_MBCFG_MASTER_ETH( strIpAddress := MBCFG_IpAddress,
uiPort := MBCFG_Port,
bUnitID := MBCFG_UnitID,
tTimeOut := MBCFG_TimeOut,
iVariableCount := zz_VARIABLECOUNT,
ptVariableList := ADR(zz_VariableList),
iJobCount := zz_JOBCOUNT,
ptJobList := ADR(zz_JobList),
tRequestDelay := MBCFG_RequestDelay,
eError => MBCFG_Error,
LastJob => MBCFG_LastJob
);
%QW377 := U_L1;
%QW378 := U_L2;
%QW379 := U_L3;
Метки: author NobleD5 it- инфраструктура блог компании миран миран цод дата-центр инженерная инфраструктура мониторинг |
Инженерные системы наших дата-центров и их мониторинг, часть первая |
Отдельно стоит упомянуть ИБП, они опрашиваются непосредственно SCADA, минуя ПЛК, по SNMP-протоколу.
(* PLC_A2 *)
%QX256.0 := A2_1QF1; //присваиваем каждому биту 256го слова
%QX256.1 := A2_1QF2; //текущее состояние различных автоматов
%QX256.2 := A2_QS1;
%QX256.3 := A2_QS2;
%QX256.4 := A2_3QF1;
%QX256.5 := A2_3QF2;
%QX256.6 := A2_3QF3;
%QX256.7 := A2_3QF4;
%QX256.8 := A2_3QF5;
%QX256.9 := A2_3QF6;
%QX256.10 := A2_3QF7;
%QX256.11 := A2_3QF8;
%QX256.12 := A2_3QF9;
%QX256.13 := A2_3QF10;
%QX256.14 := A2_KM1;
%QX256.15 := A2_KM2;
(* QF1 *) //вводной автоматический выключатель № 1
%QW332 := QF1_I_L1; //токи по фазам
%QW333 := QF1_I_L2;
%QW334 := QF1_I_L3;
%QW335 := QF1_U_L12; //линейные (межфазные) напряжения
%QW336 := QF1_U_L23;
%QW337 := QF1_U_L31;
%QW338 := QF1_U_L1; //фазные (фаза-нуль) напряжения
%QW339 := QF1_U_L2;
%QW340 := QF1_U_L3;
%QW341 := QF1_P_L1; //активная мощность по фазам
%QW342 := QF1_P_L2;
%QW343 := QF1_P_L3;
%QW344 := QF1_P_Sum; //суммарная активная мощность (кВт)
%QW345 := QF1_Q_L1; //реактивная мощность по фазам
%QW346 := QF1_Q_L2;
%QW347 := QF1_Q_L3;
%QW348 := QF1_Q_Sum; //суммарная реактивная мощность (квар)
%QW349 := QF1_S_Sum; //полная мощность (кВА)
%QW350 := QF1_CosF; //коэффициент мощности
//Это работа кодогенератора CODESYS, в котором есть удобный настройщик связи
//с периферией по Modbus TCP/IP. Эта подпрограмма, в частности, отвечает
//за получение от ОВЕН МЭ110-220.3М показаний
//по трем напряжениям фаза-нейтраль
PROGRAM MBCFG_subCMS_1(* generated by config one prg for each slave *)
VAR_OUTPUT
U_L1 : WORD; (**)
U_L2 : WORD; (**)
U_L3 : WORD; (**)
/*--- system variables (read only) ----------------------------------------*/
MBCFG_IpAddress : STRING(12) := 'XXX.XXX.XXX.XXX';//IP-адрес Slave-устройства
MBCFG_Port : UINT := 502; //Порт, дефолтный
MBCFG_UnitID : BYTE := 2; //ID Slave-устройства
MBCFG_TimeOut : TIME := t#300ms; //Таймаут на получение ответа
MBCFG_RequestDelay : TIME := t#1000ms; //Задержка до следующего опроса
MBCFG_Error : MBCFG_eERROR := MBCFG_START_UP;
MBCFG_LastJob : MBCFG_typCOM_JOB;
/*-------------------------------------------------------------------------*/
END_VAR
VAR CONSTANT
zz_VARIABLECOUNT: INT := 3; (* number of variables *)
zz_JOBCOUNT : INT := 1; (* number of jobs *)
END_VAR
VAR
/*=== VARIABLE LIST =============*/
zz_VariableList : ARRAY[1..zz_VARIABLECOUNT] OF MBCFG_typVARIABLE :=
( DataType := MBCFG_TYPE_WORD,
ByteOrder := MBCFG_BYTE_ORDER_0,
BitSize := 16,
ptVar := 0,
ReadJobIndex := 1,
ReadStartBitNo := 0,
WriteJobIndex := 0,
WriteStartBitNo := 0 ),
( DataType := MBCFG_TYPE_WORD,
ByteOrder := MBCFG_BYTE_ORDER_0,
BitSize := 16,
ptVar := 0,
ReadJobIndex := 1,
ReadStartBitNo := 32,
WriteJobIndex := 0,
WriteStartBitNo := 0 ),
( DataType := MBCFG_TYPE_WORD,
ByteOrder := MBCFG_BYTE_ORDER_0,
BitSize := 16,
ptVar := 0,
ReadJobIndex := 1,
ReadStartBitNo := 64,
WriteJobIndex := 0,
WriteStartBitNo := 0
);
/*=== JOB LIST ==================*/
zz_JobList : ARRAY[1..zz_JOBCOUNT] OF MBCFG_typCOM_JOB :=
( Functioncode := 3, //Номер функции, 0x03, Read Holding Registers
ReadStartAddress := 26,//Адрес первого регистра
ReadQuantity := 5, //Кол-во регистров, которые следует прочесть
WriteStartAddress := 0,
WriteQuantity := 0,
ptReadData := 0,
ptWriteData := 0
);
zz_DataField_1_Read : ARRAY[1..5] OF WORD;
/*=== MODBUS MASTER ==============*/
zz_MBCFG_MASTER_ETH : MBCFG_MASTER_TCP;
END_VAR
/*--- for each variable -------------------------*/
zz_VariableList[1].ptVar := ADR(U_L1);
zz_VariableList[2].ptVar := ADR(U_L2);
zz_VariableList[3].ptVar := ADR(U_L3);
/*-----------------------------------------------*/
/*--- for each job -----------------------------------*/
zz_JobList[1].ptReadData := ADR(zz_DataField_1_Read);
/*----------------------------------------------------*/
/*#### START OF FIXED CODE #####################################*/
zz_MBCFG_MASTER_ETH( strIpAddress := MBCFG_IpAddress,
uiPort := MBCFG_Port,
bUnitID := MBCFG_UnitID,
tTimeOut := MBCFG_TimeOut,
iVariableCount := zz_VARIABLECOUNT,
ptVariableList := ADR(zz_VariableList),
iJobCount := zz_JOBCOUNT,
ptJobList := ADR(zz_JobList),
tRequestDelay := MBCFG_RequestDelay,
eError => MBCFG_Error,
LastJob => MBCFG_LastJob
);
%QW377 := U_L1;
%QW378 := U_L2;
%QW379 := U_L3;
Метки: author NobleD5 it- инфраструктура блог компании миран миран цод дата-центр инженерная инфраструктура мониторинг |
Монетизация приложений в iOS 11: таргетируем встроенные покупки в новом App Store |
- (BOOL)paymentQueue:(SKPaymentQueue *)queue
shouldAddStorePayment:(SKPayment *)payment
forProduct:(SKProduct *)product;
- (void)requestProducts
{
SKProductsRequest* productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"gold.iap.example.com"]];
productRequest.delegate = self;
[productRequest start];
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSArray* products = response.products;
// do some stuff
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
if (@available(iOS 11.0, *)) {
NSArray* products = response.products;
[[SKProductStorePromotionController defaultController] updateStorePromotionOrder:products completionHandler:^(NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Update store promotion order failed with error: %@", [error description]);
} else {
NSLog(@"Success");
}
}];
} else {
// Fallback on earlier versions
}
}
- (void)fetchPromotionOrder
{
if (@available(iOS 11.0, *)) {
[[SKProductStorePromotionController defaultController] fetchStorePromotionOrderWithCompletionHandler:^(NSArray * _Nonnull storePromotionOrder, NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Fetch store promotion order failed with error: %@", [error description]);
} else {
NSMutableString* productIds = [NSMutableString string];
for (SKProduct* product in storePromotionOrder) {
[productIds appendString:product.productIdentifier];
[productIds appendString:@"; "];
}
NSLog(@"Got promotion order: %@", productIds);
}
}];
} else {
// Not supported
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
if (@available(iOS 11.0, *)) {
SKProduct* product = [response.products objectAtIndex:0];
[[SKProductStorePromotionController defaultController] updateStorePromotionVisibility:SKProductStorePromotionVisibilityHide forProduct:product completionHandler:^(NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Update store promotion visibility failed with error: %@", [error description]);
} else {
NSLog(@"Success");
}
}];
} else {
// Fallback on earlier versions
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
if (@available(iOS 11.0, *)) {
SKProduct* product = [response.products objectAtIndex:0];
[[SKProductStorePromotionController defaultController] fetchStorePromotionVisibilityForProduct:product completionHandler:^(SKProductStorePromotionVisibility storePromotionVisibility, NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Fetch store promotion visibility failed with error: %@", [error description]);
} else {
NSLog(@"Promotion visibility %ld", (long)storePromotionVisibility);
}
}];
} else {
// Fallback on earlier versions
}
}
|
Монетизация приложений в iOS 11: таргетируем встроенные покупки в новом App Store |
- (BOOL)paymentQueue:(SKPaymentQueue *)queue
shouldAddStorePayment:(SKPayment *)payment
forProduct:(SKProduct *)product;
- (void)requestProducts
{
SKProductsRequest* productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"gold.iap.example.com"]];
productRequest.delegate = self;
[productRequest start];
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSArray* products = response.products;
// do some stuff
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
if (@available(iOS 11.0, *)) {
NSArray* products = response.products;
[[SKProductStorePromotionController defaultController] updateStorePromotionOrder:products completionHandler:^(NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Update store promotion order failed with error: %@", [error description]);
} else {
NSLog(@"Success");
}
}];
} else {
// Fallback on earlier versions
}
}
- (void)fetchPromotionOrder
{
if (@available(iOS 11.0, *)) {
[[SKProductStorePromotionController defaultController] fetchStorePromotionOrderWithCompletionHandler:^(NSArray * _Nonnull storePromotionOrder, NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Fetch store promotion order failed with error: %@", [error description]);
} else {
NSMutableString* productIds = [NSMutableString string];
for (SKProduct* product in storePromotionOrder) {
[productIds appendString:product.productIdentifier];
[productIds appendString:@"; "];
}
NSLog(@"Got promotion order: %@", productIds);
}
}];
} else {
// Not supported
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
if (@available(iOS 11.0, *)) {
SKProduct* product = [response.products objectAtIndex:0];
[[SKProductStorePromotionController defaultController] updateStorePromotionVisibility:SKProductStorePromotionVisibilityHide forProduct:product completionHandler:^(NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Update store promotion visibility failed with error: %@", [error description]);
} else {
NSLog(@"Success");
}
}];
} else {
// Fallback on earlier versions
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
if (@available(iOS 11.0, *)) {
SKProduct* product = [response.products objectAtIndex:0];
[[SKProductStorePromotionController defaultController] fetchStorePromotionVisibilityForProduct:product completionHandler:^(SKProductStorePromotionVisibility storePromotionVisibility, NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Fetch store promotion visibility failed with error: %@", [error description]);
} else {
NSLog(@"Promotion visibility %ld", (long)storePromotionVisibility);
}
}];
} else {
// Fallback on earlier versions
}
}
|
Монетизация приложений в iOS 11: таргетируем встроенные покупки в новом App Store |
- (BOOL)paymentQueue:(SKPaymentQueue *)queue
shouldAddStorePayment:(SKPayment *)payment
forProduct:(SKProduct *)product;
- (void)requestProducts
{
SKProductsRequest* productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"gold.iap.example.com"]];
productRequest.delegate = self;
[productRequest start];
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSArray* products = response.products;
// do some stuff
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
if (@available(iOS 11.0, *)) {
NSArray* products = response.products;
[[SKProductStorePromotionController defaultController] updateStorePromotionOrder:products completionHandler:^(NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Update store promotion order failed with error: %@", [error description]);
} else {
NSLog(@"Success");
}
}];
} else {
// Fallback on earlier versions
}
}
- (void)fetchPromotionOrder
{
if (@available(iOS 11.0, *)) {
[[SKProductStorePromotionController defaultController] fetchStorePromotionOrderWithCompletionHandler:^(NSArray * _Nonnull storePromotionOrder, NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Fetch store promotion order failed with error: %@", [error description]);
} else {
NSMutableString* productIds = [NSMutableString string];
for (SKProduct* product in storePromotionOrder) {
[productIds appendString:product.productIdentifier];
[productIds appendString:@"; "];
}
NSLog(@"Got promotion order: %@", productIds);
}
}];
} else {
// Not supported
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
if (@available(iOS 11.0, *)) {
SKProduct* product = [response.products objectAtIndex:0];
[[SKProductStorePromotionController defaultController] updateStorePromotionVisibility:SKProductStorePromotionVisibilityHide forProduct:product completionHandler:^(NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Update store promotion visibility failed with error: %@", [error description]);
} else {
NSLog(@"Success");
}
}];
} else {
// Fallback on earlier versions
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
if (@available(iOS 11.0, *)) {
SKProduct* product = [response.products objectAtIndex:0];
[[SKProductStorePromotionController defaultController] fetchStorePromotionVisibilityForProduct:product completionHandler:^(SKProductStorePromotionVisibility storePromotionVisibility, NSError * _Nullable error) {
if(error != nil) {
NSLog(@"Fetch store promotion visibility failed with error: %@", [error description]);
} else {
NSLog(@"Promotion visibility %ld", (long)storePromotionVisibility);
}
}];
} else {
// Fallback on earlier versions
}
}
|
[recovery mode] Индия приняла закон о «выключении» интернета |
Метки: author VASExperts it- инфраструктура блог компании vas experts vas experts индия блокировка закон |
[recovery mode] Индия приняла закон о «выключении» интернета |
Метки: author VASExperts it- инфраструктура блог компании vas experts vas experts индия блокировка закон |