Пророк в 1С




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2024-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 не будет опубликован. Обязательные поля помечены *