Установка PHP 7.4 на RedOS 8.0

Ситуация: после обновления с RedOS 7.3 до RedOS 8.0, обновился и интерпретатор PHP с 7.4. до 8.1, что к сожалению сломало работу сайта на Bitrix. Нужна установка PHP 7.4 на RedOS 8.0

Задача: сделать даунгрейд PHP 8.1 на PHP 7.4

Решение: Штатным образом в RedOS 8.0 отсутствует возможность установки PHP 7.4, Но! так как RedOS по сути своей совместим с RedHat/CentOS, значит возможно использовать сторонние репозитарии http://rpms.remirepo.net.

Создадим в папке /etc/yum.repos.d файл remi.repo с содержимым:

# Repository: http://rpms.remirepo.net/
# Blog:       http://blog.remirepo.net/
# Forum:      http://forum.remirepo.net/

[remi]
name=Remi's RPM repository for Enterprise Linux 7 - $basearch
mirrorlist=http://cdn.remirepo.net/enterprise/7/remi/mirror
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi

И файл remi-php74.repo:

# This repository only provides PHP 7.4 and its extensions
# NOTICE: common dependencies are in "remi-safe"

[remi-php74]
name=Remi's PHP 7.4 RPM repository for Enterprise Linux 7 - $basearch
baseurl=http://rpms.remirepo.net/enterprise/7/php74/$basearch/
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi

После чего останется удалить php8:

dnf remove php php-common

И установить взамен php 7.4:

dnf install -y php74-php php74-php-gd php74-php-fpm php74-php-pdo php74-php-json php74-php-imap php74-php-intl php74-php-json php74-php-soap php74-php-bcmath php74-php-xmlrpc php74-php-mysqlnd php74-php-mbstring php74-php-zip
dnf install php74-php-fpm
systemctl enable php74-php-fpm
systemctl start php74-php-fpm
systemctl restart httpd

После чего можно увидеть результат:

установка PHP 7.4 на RedOS 8.0
установка PHP 7.4 на RedOS 8.0

Реле времени своими руками

Долго ли, коротко ли, но вот взяло и перестало работать реле времени на моём септике на даче. Его задачей было — раз в час, включать на 15 минут циркуляционный дренажный насос. А так как покупать новое реле «это не наш метод», было принято решение разработать реле времени своими руками. Максимально дешевое, максимально компактное. Итак, именно поэтому будем использовать микросхему attiny85:

реле времени своими руками

Купить её можно дешевле 100 руб. Так-же из хотелок, подумал , что не плохо бы видеть сколько осталось времени до включения реле и выключения реле. Следовательно будем использовать семи сегментый индикатор.

Включением-выключением насоса будет заниматься реле:

Чуть посчитав количество требуемых ног у микросхемы, взгруснул — для индикатора требуется 7 ног, плюс на реле одна. А у микросхемы всего 6 выходов. Значит придётся использовать сдвиговый регистр. Задача уже не получается совсем простой, но тем не менее остаётся вполне решаемой.

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

Итак, вырисовался в конце концов следующий алгоритм работы всего этого набора электронники: на индикаторе последовательно сменяются цифры от 9 до 0. Цифры сменяются с интервалом в 6 минут. При достижении 1, включается реле, которое выключается при достижении 0. И так по циклу. Т.е. реле (ну и насос) работает 12 минут из часа.

Общая схема подключения получилась такой:

реле времени своими руками

А скетч такой:

int dataPin =  1;   // к выводу 14 регистра DS
int clockPin = 2;   // к выводу 11 регистра (SH_CP)
int latchPin = 0;   // к выводу 12 регистра (ST_CP)
int PIN_RELAY= 4;   // управление реле 
int pause=1000;     // интервал переключения цифр

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  digitalWrite(latchPin, LOW);
  digitalWrite(PIN_RELAY, HIGH); // Выключаем реле - посылаем высокий сигнал    
}

void PritNum(int num){
  digitalWrite(latchPin, LOW); // начинаем передачу данных
   switch(num){
     case 0: 
            shiftOut(dataPin, clockPin, LSBFIRST, 0b10001000^0b00001000);break;    
     case 1: 
            shiftOut(dataPin, clockPin, LSBFIRST, 0b11101011);break;    
     case 2: 
            shiftOut(dataPin, clockPin, LSBFIRST, 0b01001100);break;    
     case 3: 
            shiftOut(dataPin, clockPin, LSBFIRST, 0b01001001);break;    
     case 4: 
            shiftOut(dataPin, clockPin, LSBFIRST, 0b00101011);break;    
     case 5: 
            shiftOut(dataPin, clockPin, LSBFIRST, 0b00011001);break;    
     case 6: 
            shiftOut(dataPin, clockPin, LSBFIRST, 0b00011000);break;    
     case 7: 
            shiftOut(dataPin, clockPin, LSBFIRST, 0b11001011);break;    
     case 8: 
            shiftOut(dataPin, clockPin, LSBFIRST, 0b00001000);break;    
     case 9: 
            shiftOut(dataPin, clockPin, LSBFIRST, 0b00001001);break;                  
   }
  digitalWrite(latchPin, HIGH); // прекращаем передачу данных
}

void loop() {
  for (int counter = 9; counter >=0; counter -- ) {
    PritNum(counter);
    pinMode(PIN_RELAY, OUTPUT); // Объявляем пин реле как выход
    if (counter==0){
      digitalWrite(PIN_RELAY, HIGH);
    };
    if (counter!=0){
      digitalWrite(PIN_RELAY, LOW);
    };
    delay(pause);
  }
}

На эмуляторе работу скетча можно посмотреть здесь

1С: Ускорение поиска в массиве структур

Задача: есть два массива структур. Один 500 записей, второй — порядка 900 тыс. Нужно для каждой из 500 записей, найти соответствующую запись из второй структуры.

ИсходныеДанные=Новый Структура("субабоненты,реестр_замен",Новый Массив(),Новый Массив(),Новый Массив(),Новый Массив());
  • Массив «субабоненты», заполнен структурами вида «то,лс,ипу,окпу,нс,улица,дом,квартира»
  • Массив «реестр_замен», заполнен структурами вида «лс,нп,улица,дом,квартира,ипу,дата_установки»

Решение 1: ищем и сопоставляем в «лоб»

	найдено=0;
	для каждого суб из ИсходныеДанные.субабоненты цикл
		    поз=поз+1;
			для каждого стр из ИсходныеДанные.реестр_замен цикл			
				если суб.лс=стр.лс тогда
					найдено=найдено+1;		
				конецесли;	
			конеццикла;
	конеццикла;	
	сообщить("-сопоставлено лс: "+найдено);	

Замеряем время выполнения…и устаём ждать.. Поиск и сопоставление длится по крайне мере несколько часов..

Решение 2:

А зачем нам в массиве субабонентов держать те данные, которых нет? Правильно, не зачем. Поэтому из массива «реестр_замен», сначала вычленим список л/с, и положим его в отдельный массив. И далее при заполнении из файла массива субабонентов, нужно штатно (функция Найти) проверять нужна такая строчка или нет в результирующем массиве? Функция «Найти» скажем работает ОЧЕНЬ быстро.

					если ИсходныеДанные.список_лс.Найти(инф.лс)<>неопределено или ИсходныеДанные.список_ипу.Найти(инф.ипу)<>неопределено тогда
						ИсходныеДанные.субабоненты.Добавить(инф);			                                                
					конецесли;

В итоге, в массиве «субабоненты» у нас ровно то количество записей, которое в «реестр_замен «, а вовсе не 900тыс.

И дальше пробуем снова сопоставить:

найдено=0;
	для каждого суб из ИсходныеДанные.субабоненты цикл
		    поз=поз+1;
			для каждого стр из ИсходныеДанные.реестр_замен цикл			
				если суб.лс=стр.лс тогда
					найдено=найдено+1;		
				конецесли;	
			конеццикла;
	конеццикла;	
	сообщить("-сопоставлено лс: "+найдено);	

Скрипт выполнился уже в приемлемые примерно 400 секунд

Чтение большого файла csv в 1С

Куда ни глянь, в интернете чаще всего предлагается обработка и чтение большого файла csv в 1С при помощи загрузки в «текстовыйДокумент». Примерно так:

ТекстДок = Новый ТекстовыйДокумент;
ТекстДок.Прочитать(ИмяВременногоФайлаХар);
Для Индекс = 2 По ТекстДок.КоличествоСтрок() Цикл
СтрокаФайла = ТекстДок.ПолучитьСтроку(Индекс);
конеццикла;

Что в корне не верно, при обработке большого csv файла, так как в этом случае весь файл вычитывается предварительно в память. А она не безразмерная в большинстве случаев. Правильный же способ обработки — построчное чтение файла. Примерно так:

		Текст = Новый ЧтениеТекста(ИмяВременногоФайлаХар, КодировкаТекста.ANSI);
		Стр = Текст.ПрочитатьСтроку();
		Пока Стр <> Неопределено Цикл 
		   Сообщить(Стр);
		   Стр = Текст.ПрочитатьСтроку();
			МассивПодстрок = СтрРазделить(Стр, ";");
			инф=Новый Структура("то,лс,ипу,окпу,нс,улица,дом,квартира");
			инф.то		=СокрЛП(МассивПодстрок[2]);
			инф.лс		=СокрЛП(СтрЗаменить(МассивПодстрок[3],"-",""));
			инф.ипу		=СокрЛП(МассивПодстрок[31]);
			инф.окпу	=СокрЛП(МассивПодстрок[92]);
			инф.нс		=СокрЛП(МассивПодстрок[8]);
			инф.улица	=СокрЛП(МассивПодстрок[9]);
			инф.дом		=СокрЛП(МассивПодстрок[10]);
			инф.квартира=СокрЛП(МассивПодстрок[11]);
			ИсходныеДанные.субабоненты.Добавить(инф);			
		   КонецЦикла; 		
	

Чтиво за последнее время

Давно не писал в эту рубрику «чтиво за последнее время». Забыл, забегался да и дачный сезон 😉

Жорж-иномирец 1-4. Автор: Сергей Панченко. Сюжет: обычный человек после ДТП получил возможность ходить между измерениями, коих бесконечно. Там он находит друзей ну и разные приключения конечно. Читабельность: 4

Попаданец с огромным потенциалом. Автор: Сергей Полев. Сюжет: хорошо поживший в своём мире человек попадает в другое измерение в другое тело. Там где магия и приключения. Читабельность 4.

чтиво за последнее время

Триллионер из трущеб 1-4. Автор: Сергей Полев. Сюжет: Попаданец в мир где правит система. Обладает уникальным навыком — тратить заработанные деньги на бесконечную прокачку навыков. Читабельность 3.

Грани. Автор: Валентин Дмитриев. Сюжет: Два друга встречают основательницу загадочной фирмы «Пирамида», которая может исполнять любые желания. Читабельность 2. Не дочитал..

Звёзды — холодные игрушки. Автор: Сергей Лукьяненко. Третья или четвертая перечитка уже. Читабельность 5 😉

Сборник Гаджет 1-10. Автор: Сергей Лукьяненко. Сборник фантастических рассказов на различные тематики. Читабельность 4.

Остальное моё чтиво тут

1 22 23 24 25 26 310