PHP Curl: Segmentation fault

Столкнулся со странной ошибкой на Astra Linux, а именно если вызывать:

curl --insecure 'https://esia.gosuslugi.ru/login/'

То получаем ошибку:

Хотя в любом другом дистрибутиве получаю стандартное:

ошибка сегментирования

Начал рыть….долго и упорно… искал разницу между установленными версиями curl. И единственное что по большому счёту отличало версию Astra Linux — поддержка сертификатов шифрования ГОСТ. А сайт Госуслуг именно их и использует. Причем шифрование на этом сайте версии 1.3. А что если попробовать принудительно попросить curl именно это шифрование? И в правду заработало:

curl --insecure  --tlsv1.3  'https://esia.gosuslugi.ru/login/'

На PHP аналог выставления данного флага:

curl_setopt ($ch, CURLOPT_SSLVERSION , CURL_SSLVERSION_TLSv1_3);

Хотя конечно остаются вопрос, почему просто падает не показывая почему..

И снова проект на Arduino: подсветка лестницы

Сей проект должен решить задачу подсветки лестницы в темноте при обнаружении движения одним из двух датчиков. Ну бонусом — кнопка принудительного включения и кнопка «новогодних эффектов». Подсветка осуществляется при адресной 5 вольтовой светодиодной ленты, с внешним питанием.

Разработку платы вёл традиционно в веб версии EasyEDA, Принципиальная схема получилась следующая:

А вот тут она-же, но уже в виде текстолитовой однослойной платы, которую вполне можно потравить и самому:

В «железе» пока еще готового варианта нет, детальки едут и Китая и прочих источников, но теоретическую модель в эмуляторе уже можно потрогать тут:

https://wokwi.com/projects/417413301092687873

Код следующий:

#include <Adafruit_NeoPixel.h>
#include <SPI.h>
#include "button.h"
button btn1(9);    // указываем пин кнопки включения/выключения света 
button btn2(12);    // указываем пин кнопки включения/выключения эффектов
boolean button_state; // текущее состояние ленты по кнопке свет вкл/выкл
boolean button_effect; // текущее состояние ленты по кнопке эффектов
#define PIN_PHOTO_SENSOR A0
int pirPin1 = 3;
int pirPin2 = 5;
#define LED_COUNT 16
#define LED_PIN 7

Adafruit_NeoPixel LED_Ring = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pinMode(13, OUTPUT);   
  pinMode(pirPin1, INPUT);
  pinMode(pirPin2, INPUT);
  button_state=false;
  LED_Ring.begin(); 
}

void button_press(){
      button_state=!button_state;
      if (button_state==true){
        digitalWrite(13, HIGH);
        for (int i = 0; i < LED_COUNT; i++){
          LED_Ring.setPixelColor(i, LED_Ring.Color(255,255, 0));
          LED_Ring.show();
        };
      } else {
        digitalWrite(13, LOW);
        for (int i = 0; i < LED_COUNT; i++){
          LED_Ring.setPixelColor(i, LED_Ring.Color(0,0, 0));
          LED_Ring.show();
        };        
      };
      delay(1000);
}
// показываем всякие эффекты, пока снова не нажманута любая кнопка
void button_effect_press(){
  int randLed;
  int randR;
  int randG;
  int randB;
  while(true){
    if (btn1.click()) {break;};
    if (btn2.click()) {break;};
    randLed = random(0, LED_COUNT);
    randR = random(0, 255);
    randG = random(0, 255);
    randB = random(0, 255);
    LED_Ring.setPixelColor(randLed, LED_Ring.Color(randR,randG, randB));
    LED_Ring.show();
    delay(100);
  }
}  
void sleep(int ms){
  unsigned long time_old; 
  time_old = millis();
  while(true){
    if (btn1.click()) {button_press();};
    if ((millis()- time_old) >= ms){
      break;
    }
  };
}
void loop() {
  while(true){
    if (btn1.click()) {button_press();}; //нажата кнопка включения-выключения света
    if (btn2.click()) {delay(1000);button_effect_press();}; //нажата кнопка включения-выключения света

    int light_level = analogRead(PIN_PHOTO_SENSOR); // если >300, то считаем что и так светло
    light_level=100; // для отладки - потом убрать!

    int move1 = digitalRead(pirPin1);
    int move2 = digitalRead(pirPin2);
    if ((move1 == HIGH) or (move2 == HIGH)){
      if (button_state==false){  // если свет не включен кнопкой
        if (light_level<250){    // если на леснице темно
          for (int i = 0; i < LED_COUNT; i++){
            if (move1 == HIGH){
              LED_Ring.setPixelColor(i, LED_Ring.Color(255, 0, 0)); // Красный цвет.
            } else {
              LED_Ring.setPixelColor(LED_COUNT-i-1, LED_Ring.Color(255, 0, 0)); // Красный цвет.
            };
            LED_Ring.show();
            sleep(300);
            if (button_state==true){break;};
          };
          if (button_state==false){
            for (int i = 0; i < LED_COUNT; i++){
              LED_Ring.setPixelColor(i, LED_Ring.Color(0, 0, 200));
            };
            LED_Ring.show();
            sleep(6000);
            for (int i = 0; i < LED_COUNT; i++){
              if (move1 == HIGH){
                LED_Ring.setPixelColor(i, LED_Ring.Color(0, 0, 0)); // Красный цвет.
              } else {
                LED_Ring.setPixelColor(LED_COUNT-i-1, LED_Ring.Color(0, 0, 0)); // Красный цвет.
              };
              LED_Ring.show();
              sleep(300);
              if (button_state==true){break;};
            };              
          };
        }
      };
    };
  };

}

Печать на принтере TSC-210 из консоли

В ходе эксплуатации принтера этикеток TSC-210 в среде 1С под Linux выявилась особенность, что он не выдерживает правильные отступы при печати, даже при установке нужных параметров бумаги. Выходом явилось сохранение печати в файл, а затем печать полученного файла при помощи просто скрипта вида:

#!/usr/bin/sh
lpr -P цув-tsc210-03 -o portrait -o media=Custom.58x28mm -o page-top=5 -o page-bottom=1 -o page-left=1 -o page-right=1 -o page-border=none ~/Документы/вывод.ps

Яндекс OCR: разметка данных

В ходе использования облака Yandex OCR для распознавания данных, выявилось что при анализе получаемого на выходе JSON, очень не достаёт визуализации полученных данных. Для того чтобы эту ситуацию чуть улучшить, написал скриптик, который на входе получает картинку для распознавания и JSON полученный от Яндекса, а на выходе выдаёт картинку с нанесенными распознанными блоками и таблицами.

Собственно код:

<?php
$res=json_decode(file_get_contents("res.json"));  // прочитаем json
$source = imagecreatefromjpeg ("pdfs/11-1.jpg");
$pink = imagecolorallocate($source, 255, 105, 180);
$white = imagecolorallocate($source, 255, 255, 255);
$green = imagecolorallocate($source, 132, 135, 28);
$blue = imagecolorallocate($source, 0, 0, 255);

// размечаю блоки
$bl=0;
foreach ($res->result->textAnnotation->blocks as $block) {    
    $kof=1.5;
    $points=[];
    $points[]=$block->boundingBox->vertices[0]->x*$kof;
    $points[]=$block->boundingBox->vertices[0]->y*$kof;
    $points[]=$block->boundingBox->vertices[1]->x*$kof;
    $points[]=$block->boundingBox->vertices[1]->y*$kof;
    $points[]=$block->boundingBox->vertices[2]->x*$kof;
    $points[]=$block->boundingBox->vertices[2]->y*$kof;
    $points[]=$block->boundingBox->vertices[3]->x*$kof;
    $points[]=$block->boundingBox->vertices[3]->y*$kof;
    $points[]=$block->boundingBox->vertices[0]->x*$kof;
    $points[]=$block->boundingBox->vertices[0]->y*$kof;    
    imagepolygon($source,$points,$green);
    imagettftext($source,20,0,$points[0],$points[1],$green,"/usr/share/fonts/truetype/r7-office/ext/PTS55F.ttf",$bl);
    $bl++;
};

//размечаю таблицы
$bl=0;
foreach ($res->result->textAnnotation->tables as $table) {    
    $kof=2.1;
    $offset_x=110;
    $offset_y=10;
    $points=[];
    $points[]=$table->boundingBox->vertices[0]->x*$kof+$offset_x;
    $points[]=$table->boundingBox->vertices[0]->y*$kof+$offset_y;
    $points[]=$table->boundingBox->vertices[1]->x*$kof+$offset_x;
    $points[]=$table->boundingBox->vertices[1]->y*$kof+$offset_y;
    $points[]=$table->boundingBox->vertices[2]->x*$kof+$offset_x;
    $points[]=$table->boundingBox->vertices[2]->y*$kof+$offset_y;
    $points[]=$table->boundingBox->vertices[3]->x*$kof+$offset_x;
    $points[]=$table->boundingBox->vertices[3]->y*$kof+$offset_y;
    $points[]=$table->boundingBox->vertices[0]->x*$kof+$offset_x;
    $points[]=$table->boundingBox->vertices[0]->y*$kof+$offset_y;    
    imagepolygon($source,$points,$blue);
    imagettftext($source,20,0,$points[0],$points[1],$blue,"/usr/share/fonts/truetype/r7-office/ext/PTS55F.ttf",$bl);
    $bl++;
    
}
imagejpeg($source, 'out.jpg');

Получаем картинку вида:

разметка на основе Yandex.ocr

PHP и его странная математика

Столкнулся с очень чудесной ошибкой на PHP:

<?php
$a=1.15;
$b=$a*100;
var_dump($b);
echo $b;
echo "\n";
?>

Что вы ожидаете увидеть в выводе? 115? А вот и нет. Если echo выведет 115, то var_dump выведет 114.99999

Что не так с float?

Тип float в языке PHP, как и его “родственник” тип double, вовсе не предназначен для точного представления десятичных дробей. Всё что мы записали в float, хранится в приближенном значении, с некоторой погрешностью.

Решение: в виду того что в PHP это считается фичей, а не багом, то для точной работы с математикой нужно использовать модуль bcmath. Ну или использовать округления до нужной точности

P.S. Не первый раз уже вспотыкаюсь об это

1 2