Пророк в 1С




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2026-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

40 Comments

  1. Дмитрий74Чел

    А какой прикладной смысл / ценность для «обычных» баз 1С УТ и т.п.?

    Reply ↓
  2. Soloist

    (1) Прогнозирование продаж и любые другие прогнозы для стратегического плана компании.

    Reply ↓
  3. olegtymko

    Интересная технология. С каким объемом данных она может работать? В каком масштабе ее используете, если не секрет?

    Reply ↓
  4. Stepa86

    (3) Пророк это либа по предсказанию временного ряда, на вход подается дата и значение. 5 лет данных, то есть табличку 2 * 3800 чисто питоновский код обрабатывает секунд за 5 на слабеньком ноуте.

    В основе лежит разделение на тренд, сезонности и вариации. Чтоб сезонность учитывалась корректно — нужно хотя бы 2 полных цикла. То есть, если есть недельная сезонность — нужно подать истории на 2 недели минимум. Если есть годовая сезонность — за 2 года минимум.

    Для просто взять либо и построить прогноз — результаты очень хорошие у этого пророка.

    Для промышленного использования могут быть ограничения- 1000 номенклатурных позиций будет обсчитываться минимум 5000 секунд, точность может быть по некоторым позициям хуже, чем другие подходы, типа простенькой регрессии, данные нужно предобрабатывать — чистить от выбросов, учитывать акции (Пророк это умеет, но текущая реализация еще нет), как нить изменить входные данные (Бокс-Кокс иногда очень хорошо улучшает точность, он в статье на хабре описан), ну и в конце нужно будет еще решить, а что же делать на основе этих данных.

    Если сравнивать с самым «крутым алгоритмом по предсказанию временного ряда» SARIMA — этот намного проще и намного быстрее и требует меньше настроек гиперпараметров

    Reply ↓
  5. Soloist

    (3) Stepa86 правильно всё подметил. Добавлю то, что я прогнозировал по месяцам 20 000 позиций с глубиною в три года (это 36 точек на позицию) за ~5 часов.

    Думаю можно всё распараллелить, но пока до этого руки не дошли. Т.е. веб-сервер должен держать… вот код 1С под это надо будет менять.

    Reply ↓
  6. FesenkoA

    Уже рассчитали количество просмотров рейтинга/загрузок этого поста? Поделитесь, а мы проверим)

    Reply ↓
  7. ImHunter

    По идее, это использование ф-буковской библиотеки на R. R, в свою очередь, уже встроен в MSSQL начиная с 2016. Так что, у кого есть лицензии, можно и в эту сторону покопать. И использовать не только Prophet, а еще уйму других библиотек.

    Reply ↓
  8. Goleff74

    Там обычный персептрон или поглубже что-то в библиотеке?

    Reply ↓
  9. Rustig

    (0) картинку пострашнее не мог найти?

    Reply ↓
  10. Soloist

    (6) Нет, но могу сказать, что в моих тестах прогнозы были ~30%. Надо набрать историю. В целом, можно инфостарт спрогнозировать посещаемость. Но это я пока оставлю как домашнее задание;)

    Reply ↓
  11. Soloist

    (8) Думаю, что там чисто математика. Опираясь на статью https://habr.com/company/ods/blog/323730/ могу лишь сказать, что для меня, как новичка в этом деле, эта библиотека показывает очень хорошие результаты без каких-либо настроек.А если покрутить…

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

    Reply ↓
  12. McSim_

    Как эксперимент, неплохо. Наверное, интересно было поразбираться.

    Но без гиперпараметров, без добавления признаков (регрессия или нет, алгоритм позволяет, странно не воспользоваться). Следить за временным рядом без возможности внести корректировки в алгоритм расчёта прогноза особого смысла нет. Интересно-то как раз, что повлияло и насколько дополнительный признак добавляет точности в предсказание. А с подобной точностью и товаровед предскажет. 🙂

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

    Не смотрел фейсбуковскую библиотеку, но наверняка там есть возможность.

    Reply ↓
  13. Soloist

    (14) Согласен, регрессию добавить можно. Надо делать:)

    Reply ↓
  14. mashinist

    установил Docker CE.

    docker version

    Client:

    Version: 18.03.1-ce

    API version: 1.37

    Go version: go1.9.5

    Git commit: 9ee9f40

    Built: Thu Apr 26 07:12:48 2018

    OS/Arch: windows/amd64

    Experimental: false

    Orchestrator: swarm

    Server:

    Engine:

    Version: 18.03.1-ce

    API version: 1.37 (minimum version 1.24)

    Go version: go1.9.5

    Git commit: 9ee9f40

    Built: Thu Apr 26 07:21:42 2018

    OS/Arch: windows/amd64

    Experimental: false

    Дальше делаю и получаю

    docker run -p 4000:80 hardandheavy/eye-prophet

    Unable to find image ‘hardandheavy/eye-prophet:latest’ locally

    latest: Pulling from hardandheavy/eye-prophet

    C:Program FilesDockerDockerResourcesindocker.exe: image operating system «linux» cannot be used on this platform.

    See ‘C:Program FilesDockerDockerResourcesindocker.exe run —help’.

    что-то пошло не так…

    Reply ↓
  15. Soloist

    (16) Возможно при установке докера была поставлена галочка использования Windows контейнеров взамен Linux https://www.screencast.com/t/i75Lof8xi

    Но это всегда можно переключить обратно нажав на правую кнопку мыши по значку и запустив Linux машину.

    Для примера можно набрать

    docker run hello-world

    Эта команда должна всегда работать

    Reply ↓
  16. mashinist

    (18) Да. Получилось вот что

    docker run -p 4000:80 hardandheavy/eye-prophet

    Unable to find image ‘hardandheavy/eye-prophet:latest’ locally

    latest: Pulling from hardandheavy/eye-prophet

    C:Program FilesDockerDockerResourcesindocker.exe: image operating system «linux» cannot be used on this platform.

    See ‘C:Program FilesDockerDockerResourcesindocker.exe run —help’.

    PS C:Usersdomiu> docker run -p 4000:80 hardandheavy/eye-prophet

    Unable to find image ‘hardandheavy/eye-prophet:latest’ locally

    latest: Pulling from hardandheavy/eye-prophet

    911c6d0c7995: Pull complete

    01a7b783f4b1: Pull complete

    fd42853239cf: Pull complete

    9a8472db1c97: Pull complete

    dc0e7e688ba4: Pull complete

    c21395580328: Pull complete

    38a300e1f9f7: Pull complete

    43bd7163e513: Pull complete

    7a30d9838573: Pull complete

    d50a5d67d0c0: Pull complete

    18c3d6fd8daa: Pull complete

    03efc69dec8c: Pull complete

    83d81bcc8bba: Pull complete

    44f1896e92fc: Pull complete

    Digest: sha256:1832652258fb0df6514835a22d4f092c1226efdbe0857a5435a1eae63cb4­de62

    Status: Downloaded newer image for hardandheavy/eye-prophet:latest

    INFO:matplotlib.font_manager:font search path [‘/usr/local/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf’, ‘/usr/local/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/afm’, ‘/usr/local/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts’]

    INFO:matplotlib.font_manager:generated new fontManager

    * Serving Flask app «app» (lazy loading)

    * Environment: production

    WARNING: Do not use the development server in a production environment.

    Use a production WSGI server instead.

    * Debug mode: off

    INFO:werkzeug: * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

    я так понимаю, что http://0.0.0.0:80 это как-то не правильно….

    Reply ↓
  17. Stepa86

    (20) Это норм. 0.0.0.0:80 это внутри контейнера, а наружу смотрит как localhost:4000

    Если Иван пересобрал мой вчерашний пулл-реквест, то работоспособность можно проверить зайдя по адресу localhost:4000/version , если все ок, то там будет 0.3 написано.

    Reply ↓
  18. mashinist

    (21) переход в браузере http://localhost:4000/version выдает 0.3

    типа все ок с docker

    изменил

    Функция ИмяСервера()

    Возврат «localhost:4000»;

    КонецФункции

    запускаю конфу

    {ОбщийМодуль._Пророк.Модуль(150)}: Ошибка получения прогноза <!DOCTYPE HTML PUBLIC «-//W3C//DTD HTML 3.2 Final//EN»>

    <title>405 Method Not Allowed</title>

    <h1>Method Not Allowed</h1>

    <p>The method is not allowed for the requested URL.</p>

    ВызватьИсключение(СообщениеПриОшибке + » » + Ответ.ПолучитьТелоКакСтроку());

    Reply ↓
  19. Stepa86
    Reply ↓
  20. comol

    Очень приятно что в 1С стали появляться люди которые «не боятся», «интересуются» и «делают». Хотя бы только для тестового примера.

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

    Reply ↓
  21. Soloist

    (22) Тысяча извинений, у вас всё хорошо. Скачайте пожалуйста новый cf. Я поменял немного ресурс по которому надо обращаться к сервису.

    После того, как понял, что для исследований некоторым будет сложен докер я решил опубликовать сервер на heroku https://eye-prophet.herokuapp.com/ попозже статью обновлю для таких ребят.

    Reply ↓
  22. mashinist

    (25) Ага. Все работает. Попробую на реальных данных в прошлом и сравню с настоящим :-)… интересно

    Reply ↓
  23. mashinist

    Прогноз на первое полугодие 2018 года по данным 2017 года

    Прогноз продаж на вторую половину 2018 года по данным 2017 и половины 2018

    Не очень оно сходится… по прогнозу продажи к концу полугодия должны были приблизится к 20, а по факту не переползли за 15

    Ради интереса попробую найти данные за последние 5 лет… Но интересно…

    Reply ↓
  24. ilyav

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

    Reply ↓
  25. Stepa86

    (28) Пророк строит прогноз как Тренд+ГодоваяСезонность+НедельнаяСезонность+ДневнаяСезонност­ь. Тренд определился как константа, для расчета годовой сезонности не хватило данных или она не была определена, дневная сезонность не актуальна. Вот и получилось, что результат прогнозирования состоит из Константа+НедельнаяСезонность

    Reply ↓
  26. Soloist

    (28) В данной конфигурации ещё не всё реализовано, но можно попробовать сменить частоту на месяц. Для этого необходимо в метод _Пророк.ПолучитьПрогноз послать третьим параметром структуру с полем Частота равной Месяц

    Так-то крутилок много, надо внедрять и крутить)

    Reply ↓
  27. Soloist

    (27) Картинки к сожалению недоступны.

    Ниже я ответил ilyav, что можно пробовать теперь как-то донастраивать Пророка. Вот после таких результатов надо крутить крутилки.

    Reply ↓
  28. borda4ev

    Вопрос, почему модель строится без фичей, это ограничение библиотеки?

    Reply ↓
  29. Stepa86

    (32) А какие фичи вы хотите закинуть в эту модель?

    В статье есть ссылка на документацию к библиотеке, там описаны все ее возможности. Эта же статья лишь о том, как можно скрестить ее с 1Ской

    Reply ↓
  30. Soloist

    (32) Я с удовольствием бы добавил фичи, если бы их потрогал. Добавить не трудно. Для меня важно понять зачем они мне нужны. А вот понять я смогу, когда возникнет потребность. Сейчас мои задачи немного ушли в другую сторону и я решил выложить, что есть, чтобы не забыть.

    Если кто-либо сможет быстрее разобраться, и поделится, то я с удовольствием добавлю с вой проект.

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

    Reply ↓
  31. Dementor

    (1) мы в свое время строили прогнозную модель для складских остатков с учетом сезонности.

    Reply ↓
  32. Hans

    почему файл конфигурции можно скачать с яндекс диска а не с Инфостарта?

    Reply ↓
  33. Stepa86

    (36) Последняя актуальная cf версия вообще на гитхабе https://github.com/HardAndHeavy/eye-prophet-cf

    Reply ↓
  34. Evgeniy_Bayd

    Класс!!! Давно пора догонять питон, а то скучно как то…

    Reply ↓
  35. Soloist

    (36) можно и так и так

    Reply ↓
  36. Soloist

    (37) Сделал одну точку через github

    Reply ↓
  37. Hans

    (39) Доржи это одобряет?

    Reply ↓
  38. Soloist

    (41) Утащил все ссылки на github. И ссылки только из одной точки, чтобы не было Яндекс.Диска, файлов публикации и github. Теперь все источники в открытом и свободном доступе.

    Спасибо за замечание, думаю теперь не будет вопросов у Доржи. Никак не хотел на этом заработать, и всё старался сделать максимально публично.

    Reply ↓
  39. Boris_1c

    Пытаюсь докер запустить на линуксовой виртуалке

    [2018-08-02 18:35:33 +0000] [6] [INFO] Starting gunicorn 19.9.0

    [2018-08-02 18:35:34 +0000] [6] [INFO] Listening at: http://0.0.0.0:80 (6)

    [2018-08-02 18:35:34 +0000] [6] [INFO] Using worker: sync

    [2018-08-02 18:35:34 +0000] [9] [INFO] Booting worker with pid: 9

    INFO:matplotlib.font_manager:font search path [‘/usr/local/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf’, ‘/usr/local/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/afm’, ‘/usr/local/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts’]

    INFO:matplotlib.font_manager:generated new fontManager

    Это последняя строка в консоли Ubuntu server

    Судя по предыдущим постам не хватает вывода:

    * Serving Flask app «app» (lazy loading)

    * Environment: production

    WARNING: Do not use the development server in a production environment.

    Use a production WSGI server instead.

    * Debug mode: off

    INFO:werkzeug: * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

    И подскажите как настроить докер что бы он был виден в локальной сети а не толькао на локальном хосте?

    Reply ↓
  40. pbabincev

    Великолепная работа!

    Reply ↓

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *