Как стать автором
Обновить
4
0

Пользователь

Отправить сообщение
Здесь нужно задать два вопроса:
1. А в скольких процентах случаев фаза «ну я же говорил» в итоге так и не наступила после этих решений?
2. Если такой процент ничтожно мал, то не кажется ли вам, что у вас в команде нездоровая атмосфера и ее надо просто сменить?
Это реально, мы часть инфы для конфли генерили из кода. Но это работает только для тех мест, которые поддерживает разработка. Пустить в репозиторий аналитиков\бизнес\саппорт может быть немного геморно со всех сторон (для одних — тюнинг прав и больше нагрузка на ревью изменений в репе, для других — необходимость изучать гит и процессы по которым это попадает в финальную доку, как посмотреть промежуточный результат без коммита и т.ж.)
Чести ради и «все константы класса» тоже нельзя, только через рефлексию. Поправьте, если ошибаюсь. Но эту ветку мы обсуждаем исходя из того что контроль типов не нужен человеку, только группировка значений

habr.com/ru/post/517752/#comment_22041126
Если нужна группировка, то можно раскошелиться и на класс
final class Action {
  public const JUMP = 1;
  public const RUN = 2;
  public const WALK = 3;
}
Если не нужен контроль типов, то кажется лучше просто набор констант тогда?
Пойдем еще дальше и добавим контроль допустимых значений через массив, а не через наличие метода. После этого можно вынести все кроме static $values в базовый родительский класс и у нас получился неплохой переиспользуемый енам

/**
 * @method static static SUMMER()
 * @method static static AUTUMN()
 * @method static static WINTER()
 * @method static static SPRING()
 */
final class Seasons
{
    private static array $mapping = [];

    private static array $values = [
        'SUMMER',
        'AUTUMN',
        'WINTER',
        'SPRING',
    ];

    private string $name;

    private function __construct(string $name)
    {
        $this->name = $name;
    }

    public static function __callStatic(string $name, array $args): self
    {
        if (!in_array($name, self::$values, true)) {
            throw new \BadMethodCallException("Value $name is not allowed");
        }

        if (!isset(self::$mapping[$name])) {
            self::$mapping[$name] = new self($name);
        }

        return self::$mapping[$name];
    }
}

понимаю, что пример наколеночный, но вижу два недостатка:
* Нет контроля типов (т.е если унести свитч в отедльный метод\набор методов, то там будет таки (string $action) в сигнатуре.
* Енам либо придется делать глобальным, либо инстанциировать в каждом месте, где его надо обработать, т.е. опять же если унести этот свитч в отдельный метод, то для проверки значений придется инстанциировать енам заново, что будет плодить этот набор значений по кодовой базе
Массив пхп не позволяет держать в ключах ничего кроме строк и интов. Для того, чтобы использовать в качестве объектов нужен некий Map, например такой.

www.php.net/manual/ru/class.ds-map.php
Мы когда то дошли до вот такого решения. github.com/paillechat/php-enum/blob/master/src/Enum.php

Работают строгие сравнения (===, in_array($value, [MyEnum::NAME1(), MyEnum::NAME2()], true) и пр.)

Косяка из комента ниже нет habr.com/ru/post/517752/#comment_22031208
Food::BEER() === Waste::BEER() не пройдет (это разные инстансы)

Обращения к рефлексии кэшируются в памяти класса и повторно используется мемори кэш вместо рефлексии при обращении к инстансам.

В целом можно было бы сделать и без рефлексии (похожий пример ниже в коментах), но первая версия этой либы работала на текстовых константах (new MyEnum(MyEnum::NAME1) ) и было решено оставить работу со списком значений через константы, а не через массив допустимых значений
Весь проект переписать на другой ЯП в тот момент когда понадобились перечисления — такая себе затея. Давайте будем честны, иногда работаем с чем есть, проекты не только создают, но и развивают существующие.
Эм, на этой страничке нет ничего про установку HA на роутер. Это инструкция как подключить роутер в качестве девайс-трекера
Как раз попалось на глаза видео про zigbee direct binding
youtu.be/xgtZazMZNto?t=202
Выглядит очень удобно — координатор жив — получаем полноценное взаимодействие, mqtt и прочее. Выключили координатор — связанные устройства все еще общаются напрямую, не нужен даже роутер.

При этом сопряжение идет через удобный UI. Кажется если научиться заливать в такие штуки сценарии подобные вашим, то будет совсем круто
Ручная прошивка и сопряжение не нужны, я такой дичи нигде не предлагал…

Неправильно выразился, да. под «каждый с каждым» я имел ввиду именно ручное распределение сценариев по устройствам

Вы кажется используете крайне примитивную прошивку, даже в моём прототипе есть протокол первоначального подключения к сети, по которому можно подключить устройство в новую сеть без перепрошивки — это стандарт для commodity устройств…

Я использую голые esp — на них ничего нет изначально, так что прошивать все равно приходится. Но вообще да, на них можно залить прошивку вообще без конфига и донастроить опосля, но если девайс воткнут у меня в сериал порт — мне проще сразу и конфиг залить

но кол-во устройств задействованных в одном сценарии не растет — сценарии задействующие десятки устройств — редкость.

Классический сценарий «погасить весь свет в доме по нажатию на кнопку» будет требовать манипуляций с перенастройкой при добавлении каждого устройства (или замены обычного светильника на умный).

— В клиент-серверной архитектуре та самая единица добавляемая к M — это убернода, выруб которой убивает всю систему — это еще снижает надежность. x Такой SkyNet сможет завалить любой Нео нашедший сервер HA/MQTT.
— Так-же есть фактор стоимости — нода под HA нередко окажется самой дорогой во всей сети

Как я уже сказал HA — вообще необязательный компонент сети, а MQTT можно развернуть на таких же esp. Выруб — да, валит всю систему. Но как уже не раз сказали вероятность такая же как вырубить роутер\центральный свитч или что у вас там за сеть отвечает, имхо

Я же в целом эту проблему решаю чуть проще (и в плане исполнения и в плане удобства). Все критические девайсы в случае отвала SPoF (mqtt\роутер) можно тыкать физически прямо через девайс. т.е. можно подойти и переключить умную розетку вручную (на них есть кнопка), подойти и выключить умный свет выключателем и т.д. Т.е я заранее строю UX так, чтобы все деградировало до обычного «неумного» дома в случае проблем с девайсами

Но я процитирую соседний ответ
Не сочтите за критику, Ваше решение мне очень понравилось.

Мне кажется вам надо попробовать применить эту концепцию в сторону зигби девайсов. Они умеют строить меш сети где аргумент про отвал роутера больше не будет валидным ) Если присыпать это дело UI, который будет уметь заливать скрипты в девайсы — и кажется будет крутой продукт
Сейчас вы выступаете в качестве «ручного» окрестратора устройств при их конфигурации. При наличии большого количества устройств если спаривать их все вручную друг с другом займет кучу времени. Вы по сути предлагаете каждому устройству рассказать про каждое физическое устройство. Если нужно будет внести изменения, то это тоже куча работы — например отправлять данные не на одно устройство, а на 10. имея MQTT вам вообще не придется ничего модифицировать — вы просто подписываете 10 девайсов на один и тот же топик (т.е. по факту имеете 10 одинаковых девайсов с идентичной прошивкой).

Во вторых MQTT это не только точка отказа, но и точка резервации данных для устройств. Если какой-то девайс ребутался и пропустил последний пакет со стейтом то он легко может вычитать его из топика сразу при загрузке. В вашем случае он будет ожидать следующего пакета.

То что требует отдельного девайса — на той же esp можно поднять брокер

Я конечно выражаю точку зрения бытового потребителя этого всего добра. Для частного случая и единичного применения наверное это прикольно, но заставлять массового потребителя вручную прошивать и сопрягать каждое устройство с каждым ради децентрализации — выглядит оверхедом. Я заливаю на все свои устройства одинаковую прошивку с одинаковым конфигом — они знают только про вайфай сеть и mqtt брокера.
Нигде вручную не зашиваются полтора десятка айпишников (у меня устройства вообще по dhcp получают адреса)

Более того благодаря проектам типа zigbee2mqtt в эту же экосистему легко интегрируются девайсы котороые вообще не умеют в tcp\ip. Как это можно сделать с вашим подходом?
У вас нет SPoF только до тех пор пока вы все девайсы настраивайте и спаривайте вручную. Когда девайсов станет несколько десятков, то SPoF станете вы сами.

У меня полтора десятка и я бы уже задолбался каждый настраивать вручную

Но в целом та же тасмота умеет в device groups (udp multicast)
tasmota.github.io/docs/Device-Groups без mqtt если очень хочется.
Все так. По факту если брать какую-нибудь тасмоту в качестве базовой прошивки для девайсов, то на HA накладываются только несколько ролей
* Няшный интерфейс с хранением истории данных
* Интеграция более тупых сервисов в экосистему (условный смарт тв который не умеет в mqtt)
* Интеграция внешних систем в экосистему (например, подключение к google home\alexa\алисе или подключение других брендов IoT у которых нет нормальных локальных протоколов)

Все остальное успешно работает мимо HA, через mqtt и системы автоматизации типа node-red.
ну технически окружение у процесса есть всегда, а вот файл еще вычитать надо, потратив на это ресурс. во-вторых так проще запускать во всяких докерах. есть один и тот же образ с одной и той же фс без .env, а настройки задаются при запуске образа. да хоть через тот же --env-file=.env, но приложение про него не узнает — образ остается неизменным, что более гибко. можно конечно смаунтить .env в образ, но тоже не думаю что это удобно и производительно.

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


Именно в этом примере ярко демонстрируется проблема: в названии поля meail сделана опечатка и чтобы это исправить вам придется так же сделать релевантную правку в вашем API (точней она была уже сделана, если этот код работает), который в предыдущем примере был абсолютно независимым.

Но скрестив два этих RFC вместе получаем двойную проблему — мало того что имена параметров — теперь часть API, так еще и при неудачном использовании даже приватные поля класса становятся частью API, т.к. описываются через именованные параметры.

Я не то чтобы против этих нововведений, но пример, на мой взгляд, совсем не демонстрирует их преимущества, а даже наоборот — выставляет в негативном свете.
Вопрос в том, зачем вам проверять айдишник? Важно ли что он именно 5? Будет ли проблема, если 6? Может важно лишь то, что по айдишнику, который в ответ был возвращен системой лежат данные, которые вы этим запросом отправили, а какой именно айдишник вам выдали — не важно?
Представьте себе, что вместо ваших тестов сидит тестировщик и у него есть какое — то состояние приложение — он не знает какие данные туда заливали раньше. Как он будет проверять этот запрос?
Позвольте узнать, а что именно вы проверяете такое, где нужна привязка к генерируемым автоинкрементом айдишникам? На моей практике такие вещи сигнализируют об очень хрупких тестах которые дорого обслуживать и от которых мало профита.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность