Smoke

<<< Back

Как получить время езды до работы?

Быстрый, кривой, костыльный, но рабочий способ.

Зачем?

При открытии входной двери у меня планшет висящий в прихожей проговаривает погоду и время до работы, работаю я далеко в 25 км. от дома, поэтому знать время очень хотелось. Как обычно, я же не могу взять готовое и пошел костылить свое =)

Как сделать

Создаем в любой директории файл, например time_to_job.php и в него (В коде есть комментарии):

<!DOCTYPE html>
<html>
<head>
    <title>Работа с данными и событиями модели мультимаршрута</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script src="https://yandex.st/jquery/2.2.3/jquery.min.js" type="text/javascript"></script>
    <!--
        Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
        Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
    -->
    <script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&amp;apikey=<API KEY!>" type="text/javascript"></script>

    <style>
        html, body {
            width: 100%; height: 100%; padding: 0; margin: 0;
        }

        #map {
            width: 95%; height: 50%;
        }
        #viewContainer {
            margin: 8px;
        }
    </style>
    <script>
    ymaps.modules.define('MultiRouteCustomView', [
    'util.defineClass'
    ], function (provide, defineClass) {
        // Класс простого текстового отображения модели мультимаршрута.
        function CustomView (multiRouteModel) {
            this.multiRouteModel = multiRouteModel;
            // Объявляем начальное состояние.
            this.state = "init";
            this.stateChangeEvent = null;
            // Элемент, в который будет выводиться текст.
            this.outputElement = $('<div></div>').appendTo('#viewContainer');

            this.rebuildOutput();

            // Подписываемся на события модели, чтобы
            // обновлять текстовое описание мультимаршрута.
            multiRouteModel.events
                .add(["requestsuccess", "requestfail", "requestsend"], this.onModelStateChange, this);
        }

        // Таблица соответствия идентификатора состояния имени его обработчика.
        CustomView.stateProcessors = {
            init: "processInit",
            requestsend: "processRequestSend",
            requestsuccess: "processSuccessRequest",
            requestfail: "processFailRequest"
        };

        // Таблица соответствия типа маршрута имени его обработчика.
        CustomView.routeProcessors = {
            "driving": "processDrivingRoute",
            "masstransit": "processMasstransitRoute",
            "pedestrian": "processPedestrianRoute"
        };

        defineClass(CustomView, {
            // Обработчик событий модели.
            onModelStateChange: function (e) {
                // Запоминаем состояние модели и перестраиваем текстовое описание.
                this.state = e.get("type");
                this.stateChangeEvent = e;
                this.rebuildOutput();
            },

            rebuildOutput: function () {
                // Берем из таблицы обработчик для текущего состояния и исполняем его.
                var processorName = CustomView.stateProcessors[this.state];
                this.outputElement.html(
                    this[processorName](this.multiRouteModel, this.stateChangeEvent)
                );
            },

            processInit: function () {
                return "Инициализация ...";
            },

            processRequestSend: function () {
                return "Запрос данных ...";
            },

            processSuccessRequest: function (multiRouteModel, e) {
                var routes = multiRouteModel.getRoutes(),
                    result = [];
                if (routes.length) {
                    for (var i = 0, l = routes.length; i < l; i++) {
                        result.push(this.processRoute(i, routes[i]));
                    }
                    //Отправим в УД AJAX с информацией
                    //AJAX будет устанавливать в свойство ответ от Яндекса, тут думаю все понятно
                    $.ajax({
                        url: '/objects/?op=set&object=System_GPS&p=goToJob&v=' + result,
                        success: function(responce) {
                            console.log('Отправлено!');
                        },
                        error: function(responce) {
                            console.log('Ошибка отправки в УД!');
                        }
                    });
                } else {
                    result.push("Нет маршрутов.");
                }
                console.log(result);
                return result.join("<br/>");
            },

            processFailRequest: function (multiRouteModel, e) {
                return e.get("error").message;
            },

            processRoute: function (index, route) {
                // Берем из таблицы обработчик для данного типа маршрута и применяем его.
                var processorName = CustomView.routeProcessors[route.properties.get("type")];
                return this[processorName](route);
            },

            processDrivingRoute: function (route) {
                var result = [];
                result.push(this.createCommonRouteOutput(route));
                return result.join("<br/>");
            },

            processMasstransitRoute: function (route) {
                var result = ["Маршрут на общественном транспорте."];
                result.push(this.createCommonRouteOutput(route));
                result.push("Описание маршута: <ul>" + this.createMasstransitRouteOutput(route) + "</ul>");
                return result.join("<br/>");
            },

            processPedestrianRoute: function (route) {
                var result = ["Пешеходный маршрут."];
                result.push(this.createCommonRouteOutput(route));
                return result.join("<br/>");
            },

            // Метод, формирующий общую часть описания для всех типов маршрутов.
            createCommonRouteOutput: function (route) {
            //формируется строка, которая и будет отправлена в majordomo
                return "До работы " + route.properties.get("distance").text + ", время в пути " + route.properties.get("duration").text;
            },

            // Метод, строящий список текстовых описаний для
            // всех сегментов маршрута на общественном транспорте.
            createMasstransitRouteOutput: function (route) {
                var result = [];
                for (var i = 0, l = route.getPaths().length; i < l; i++) {
                    var path = route.getPaths()[i];
                    for (var j = 0, k = path.getSegments().length; j < k; j++) {
                        result.push("<li>" + path.getSegments()[j].properties.get("text") + "</li>");
                    }
                }
                return result.join("");
            },

            destroy: function () {
                this.outputElement.remove();
                this.multiRouteModel.events
                    .remove(["requestsuccess", "requestfail", "requestsend"], this.onModelStateChange, this);
            }
        });

        provide(CustomView);
    });

    function init () {
    // Создаем модель мультимаршрута.
        //Откуда и куда, откуда координаты, куда - можно просто адрес
    var multiRouteModel = new ymaps.multiRouter.MultiRouteModel([
            [56.245606, 43.841469],
            "село Федяково, сельское поселение Большеельнинский сельсовет, Кстовский район, Нижегородская область, Россия, 607686"
        ], {
            // Путевые точки можно перетаскивать.
            // Маршрут при этом будет перестраиваться.
            wayPointDraggable: true,
            boundsAutoApply: true
        }),

        // Создаём выпадающий список для выбора типа маршрута.
        routeTypeSelector = new ymaps.control.ListBox({
            data: {
                content: 'Как добраться'
            },
            items: [
                new ymaps.control.ListBoxItem({data: {content: "Авто"},state: {selected: true}}),
                new ymaps.control.ListBoxItem({data: {content: "Общественным транспортом"}}),
                new ymaps.control.ListBoxItem({data: {content: "Пешком"}})
            ],
            options: {
                itemSelectOnClick: false
            }
        }),
        // Получаем прямые ссылки на пункты списка.
        autoRouteItem = routeTypeSelector.get(0),
        masstransitRouteItem = routeTypeSelector.get(1),
        pedestrianRouteItem = routeTypeSelector.get(2);

    // Подписываемся на события нажатия на пункты выпадающего списка.
    autoRouteItem.events.add('click', function (e) { changeRoutingMode('auto', e.get('target')); });
    masstransitRouteItem.events.add('click', function (e) { changeRoutingMode('masstransit', e.get('target')); });
    pedestrianRouteItem.events.add('click', function (e) { changeRoutingMode('pedestrian', e.get('target')); });

    ymaps.modules.require([
        'MultiRouteCustomView'
    ], function (MultiRouteCustomView) {
        // Создаем экземпляр текстового отображения модели мультимаршрута.
        // см. файл custom_view.js
        new MultiRouteCustomView(multiRouteModel);
    });

}

ymaps.ready(init);

    </script>
</head>

<body style="overflow: hidden;">
    <div id="viewContainer"></div>
</body>

</html>

В итоге если откроете этот файл увидите:

До работы 25 км, время в пути 44 мин.

Маршрут естественно строится с учетом пробок.

Далее, нужно заставить обновлятся эти данные, так как это Яндекс у них не все так просто, как могло было быть, поэтому костылим. Актуально для тех, у кого висит планшет как у меня.
На сцену добавляем скрытый фрейм и релодим его каждые 2 минуты с помощью JQ

<iframe id="timeToJobFrame" style="display:none;border: 0px;overflow: hidden;height: 50px;width: 100%;" src="/auto/maps.php"></iframe>
<script>
$(function() {
            setInterval(function() { 
                var iframe = document.getElementById('timeToJobFrame');
                iframe.src = iframe.src;
            }, 1800000);
        });
</script>

Discuss (4) (9)

See also:
2020-11-04 Проксирование WebSocket с wss:// -> ws://
2020-06-02 Стилизация штатного редактора кода, часть 2
2020-06-01 Распознавание речи - бесплатно, просто, быстро.
2020-06-01 Стилизация штатного редактора кода
2020-01-29 Парсим данные баланса из ЛК Билайн (Update)
2020-01-28 Camshoter на свой лад
2020-01-21 Google Location + Yandex Maps, на свой лад
2020-01-19 Получение Я.Погоды из сценария
2020-01-17 Рассказ хейтера сцен в MJDM. Часть 2
2020-01-17 Как можно НЕ использовать сцены в MJDM. Часть 2
2020-01-16 Перезагружаем роутер Zyxel из MJDM
2019-12-12 Как подружить Camshoter и обычную вебку
2019-10-07 Управление планшетом из сцен/WEB
2019-10-07 Использование злосчастных WebSoccet
2020-01-17 ~DELETED~
2019-07-23 Как можно НЕ использовать сцены в MJDM. Часть 1.

Нижний Новгород, Россия

На форуме: SmoKE_xDDD