Pull to refresh
2
0
Send message
Помнится, это работало только в каком-то древнем стандарте, NMT вроде, или как-то так. Еще направленная антенна эффект давала. А GSM с самого начала уже держал связь с несколькими точками одновременно, и вычислял удаление от каждой точки по времени ретрансляции трубкой специальной не повторяющейся последовательности цифирь.
а кто оракул? DNS штука такая, тебе одно а мне другое, например по GEO
Вознаграждение
Небольшое, или даже виртуальное, вознаграждение за целевое поведение побуждает совершать действия чаще и эффективнее


постоянно наталкиваюсь на то, как этот пункт убивает все предидущие — вы серьёзно считаете что я рад тому что я «earned badge» случайного посетителя сайта-помойки? Это палит незаметность первых четырех пунктов!
отложите архитектуру немного, изучите экранирование символов и гляньте в заголовок!
Был у меня похожий опыт, только лодка побольше и моря другие. Хотя мне повезло, и у меня лютый-бешеный резист к качке (в злую качку хочется жратъ), к сожалению мечты о фрилансе с борта лодки не взлетели — днем Желтый Джек дает прикурить, вечером дольше 5 минут смотриш в экран даже при минимальной качке — находиш себя утром спящим рожей в ноутбуке. Так-что если кодить-шкотить, то только на реках наверно, а это уже не то пальто…
имхо статистика — бедность лексикона на фоне выплесков ключевиков из тех-задания — централизованно это проще отконтролить, да и проще отконтролить окружение/реализацию — не прокалываться на всяких SSL хендшейках и прочем, анонимность же не достигается приватной вкладкой
Какие-то у вас «последние» версии совсем как «первые» — с общением то какие проблемы, чат-боты общаются насыщеннее чем половина моих знакомых. И дело тут ведь не в «автоматизации», все автоматизируется джуниор-автоматизатором, а в деталях этой самой автоматизации — как бот двигает мышкой/скроллом, с какими траекториями и таймингами, причем сами траектории то создать не сложно, просто когда бот с ними «выходит в тираж» он этим и палится — «индивидуальный» почерк у него вдруг начинает совпадать с множеством таких-же инстансов бота, жадность как всегда губит… Ну и фингерпринтинг браузеров туда-же

А рассказывают нам про «спалили по артефактам нейросети», ага ага, не палить же реальные темы.
тема в паблике === мертвая тема
image

PM2 штука полезная, да, но я как-то неуверен что «запустить процесс много раз» это то, что имел ввиду Ваш оппонент. Даже если оставить в стороне различия между процессами и потоками, это все равно не про «как их пачку стартануть».
Оно не раскрывает [упс ошиб(ся|лась|лось|Лось) веткой].
разработчики… чо уж, написали бы уже — Хуавей виноват, в инструкции шайтан-коробки-маршрутизатора про latency и jitter было слишком мелким шрифтом написано…
Увы, статьей аккаунт не позволяет. По свободе заделаю git-репозиторий с кодом и примером «как помигать светодиодом» под автотестами.
Ууух, круто написано, про SOLID особенно понравилось! Предлагаю альтернативный финал: познать дзен начать писать асинхронные сокеты на асинхронном языке — вот это будет поворот! Но PHP не забывать — быстрый, прекрасный, без лишнего бойлерплейта и плоть от плоти REST и прочий stateless web. Мне вот, например, очень нравится его legacy-парадигма — бежать к финишу HTTP запроса как спринтер, разбрасывая по пути бутылки, окурки, память и хендлеры всевозможных ресурсов, все равно дворник через 10ms все приберет.
Тут дело не в даунгрейде версии, а в работоспособности OTA в новой версии — не сможем откатиться на старую (пусть и под новым номером) — значит багфикс и новую версию тоже не втянем, канал ОТА лег, уже проданные приборы — кирпичи.
ок, начну чуть издалека, сорри за фуражку Капитана Очевидности во многих моментах, имхо на них стоит сделать акцент.

«Железячные тестовые стенды» и тестируемые приборы, в отличии от «тестирования кодом кода», часто не совсем детерминированные — взаимные наводки, плохие контакты, помехи, коты и всякое такое, поэтому:

— принцип KISS на первом плане — чем меньше мы навесим тестовой обвязки — тем лучше, стараемся максимально снять инфы по визуальному каналу (вебкамера смотрит на экран тестируемых приборов и их светодиоды), там где можно тестировать демоборды или что-то с питанием от USB — берем USB хаб управляющий питанием по каждому порту (например Dlink H7 в сером корпусе) — $20 за 7 каналов управления питанием и проброса UART-или-что-там-на-борде в систему

— никаких плат разложенных по столам/полкам стендов — во первых коты, во вторых маппинг экранов/светодиодов в пиксели видеокамеры будет слетать. Например, собираем тестовые «лотки» из корпусов от старых CD приводов, и вставляем их в старый ATX корпус, где напротив них стационарно висит вебкамера (см фото). На веб-камеру стоит нацепить полярик, и не особо совать все это под солнечный свет (цвета пикселей будут уходить)

— только качественные и короткие USB провода

Фото
image
image


О фреймворке (точнее сборки из NodeJS+Redis c легаси и велосипедами) — он состоит из серверной части и самих тестов. Серверная часть выставляет веб-морду, из которой можно запустить любой тест и смотреть его прогресс и видеокамеру. (планировалась еще интерактивность, пробросить кнопки прибора в кнопки на морде, но руки пока не дошли). Так-же серверная часть обрабатывает вебкамеру, захватывая кадры через OpenCV, выделяя интересующую область и публикуя ее в Redis-канал для приема на стороне теста, и в вебсокеты UI клиентам.

На стороне теста «фреймворк» выставляет Promise обертки над всякими командами «поуправлять питанием портов USB хаба» и над i2c периферией, которая «нажимает кнопки» 16-канальным PWM драйвером, им-же эмулирует аналоговые сигналы (например, один из наших приборов {реле защиты} измеряет напряжение в сети и от него все действия, PWM хоть и точностью +-3 вольта, но эмулит пере/недо-напряжения)

Пример теста (неканонично, это все делалось для внутр. пользования)
const {
    wait ,
    waitForUart ,
    waitForPixel ,
    timeLabel ,
    infoLabel ,
    buttonPress ,
    buttonUnpress,
    sendPWM ,
    powerCycle
} = require('./test-framework');

const Stage = require('./stage-config');

const PowerLedX = 34;
const PowerLedY = 236;

const PowerReadyLedX = 53;
const PowerReasyLedY = 274;

Promise.resolve(true)
    //
    // turn on PWM driver
    .then(timeLabel("init-section","START"))
    .then(infoLabel("включаем PWM,устанавливаем напряжение входа VP16"))
    .then(powerCycle(true,Stage.PWM))
    .then(wait(500))
    // set input voltage at VP16
    .then(sendPWM(0,220/Stage.VP16.UCONST,Stage.VP16.UINP))
    .then(wait(500))
    .then(timeLabel("init-section","PASS"))
    .catch(timeLabel("init-section","FAIL"))
    .then(infoLabel("включаем VP16"))//
    .then(wait(500))
    .then(timeLabel("pwr-ready-test","START"))
    .then(powerCycle(true,Stage.VP16))
    //.then(powerCycle(true,Stage.TR16))
    .then(infoLabel("ждем готовности по напряжению"))
    .then(waitForPixel(PowerReadyLedX,PowerReasyLedY,(r,g,b,a)=>(r>200 || ((r > (g+b)*2)&&(r>30)) )))
    .then(timeLabel("pwr-ready-test","PASS"))
    .catch(timeLabel("pwr-ready-test","FAIL"))
    .then(wait(2000))
    .then(timeLabel("pwr-button-on-test","START"))
    .then(infoLabel("нажимаем среднюю кнопку"))
    .then(buttonPress(Stage.VP16.BUTTON2))
    .then(waitForPixel(PowerLedX,PowerLedY,(r,g,b,a)=>r>230))
    .then(timeLabel("pwr-button-on-test","PASS"))
    .catch(timeLabel("pwr-button-on-test","FAIL"))
    .then(infoLabel("отпускаем среднюю кнопку"))
    .then(buttonUnpress(Stage.VP16.BUTTON2))
    .then(wait(2000))
    .then(timeLabel("pwr-overvoltage-test","START"))
    .then(infoLabel("имитируем овервольтаж"))
    .then(sendPWM(0,310/Stage.VP16.UCONST,Stage.VP16.UINP))
    .then(waitForPixel(PowerLedX,PowerLedY,(r,g,b,a)=>r<230))
    .then(timeLabel("pwr-overvoltage-test","PASS"))
    .catch(timeLabel("pwr-overvoltage-test","FAIL"))
    .then(wait(2000))
    .then(infoLabel("ждем восстановления"))
    .then(wait(500))
    .then(timeLabel("pwr-overvoltage-return-test","START"))
    .then(sendPWM(0,220/Stage.VP16.UCONST,Stage.VP16.UINP))
    .then(waitForPixel(PowerLedX,PowerLedY,(r,g,b,a)=>r>230))
    .then(timeLabel("pwr-overvoltage-return-test","PASS"))
    .catch(timeLabel("pwr-overvoltage-return-test","FAIL"))
    .then(wait(2000))
    .then(infoLabel("выключаем приборы"))
    .then(powerCycle(false,Stage.VP16))
    .then(wait(500))
    .then(powerCycle(false,Stage.TR16))
    .then(wait(500))
    .then(powerCycle(false,Stage.PWM))
    .then(wait(1000))
    //.then(powerCycle(false,Stage.TR16))
    .then(timeLabel("final-section","PASS"))
    .catch(timeLabel("final-section","FAIL"))
    .then(()=>process.exit());



И пример конфига для него:
const Stage = {
    "PWM" :  {
        id: "PWM",
        usb: "8.7",
        power_hub_port: 7,
        serial: undefined
    },

    "VP16": {
        id: "VP16",
        usb: "8.1",
        power_hub_port: 1,
        serial: undefined,
        // voltage calibration
        UCONST : 0.2980,

        // pwm shield port map
        UINP    : 0, // U input emulation
        BUTTON1 : 2, // buttons...
        BUTTON2 : 1, //
        BUTTON3 : 3, //
    },
    "TR16": {
        id: "TR16",
        usb: "8.6",
        power_hub_port: 6,
        serial: undefined,
    },

    "FLASHER" :  {
        id: "FLASHER",
        usb: "8.2",
        power_hub_port: 2,
        serial: undefined
    },

};

module.exports = Stage;



Тест можно запускать из-под UI вручную, можно из cmd-line для интеграции пайплайнов да и просто с IDE по SSH (у меня CLion скриптом собирает бинарь, scp его на стенд, ssh туда, выгрузка на плату и запуск теста при необходимости — получается эмбед писать с ноута удаленно от стенда и проводов). При запуске из командной строки вывод и вэбка все-равно транслируются в UI для стороннего контроля.

Крутится все это на i5 под убунтой, жрет CPU 10..15% (в основном вэбка и ее данные по шине Redis, там не особо оптимизировать успел)

В целом получается что-то типа сильно упрощенного Redd от EasyLy ( habr.com/ru/post/440156 ) только «мясом вовнутрь» и за шапку сухарей.
ложная уверенность — плохо, но это к теории тестирования)) для OTA имхо как минимум один тест — «способен ли новый билд посредством OTA откатиться на старый» должен быть автоматизирован в пайплайне
Ну чего всего в два раза то? У нас например в стенде на пяток устройств — кнопки жимкают 16-канальные i2c PWM контроллеры, питаловом управляют они-же и USB хабы поддерживающие управление питанием портов, 7-ми-сегментники и светодиоды трекаются видеокамерой и все это счастье обмазано JS-фреймворком на промисах, разруливающий свистопляску номеров TTYUSB_N по USB-топологии, выставляющим примитивы похожие на selenium — waitForUARTtext, waitForPixel, powerCycle, buttonPress… Cбоку CI конвеер собирает из С кода + React-вебморды, после вебпака гзипуемого и транслируемого в C-литералы. Все это крееепко сложнее ESP8266+PIC прибора который тестируется.

P.S. есть идеи выложить фремворк в паблик, но как-то не заморачивался думая что мало кто в эмбеде по CI упарывается
Тут прикол немного в другом. JS то есть, но только «одобренный» партией — и поэтому 99% он уже закэширован на устройстве. Что-бы небыло одного и того-же JQuery только с разных CDN + своего хостина + немного разных минорных версий. А то шо он процессор есть, так гугл же вам его и продаст )
маркетолог отдаст правую руку


вот уж чью руку точно не жалко ))
А что нам эти закладки, когда каждая нога микросхемы под контролем ??? Как они активируются/протекут, эти закладки — там есть свой модем с антенной прямо на кристалле???
Если подтереть альтернативные потоки файла (или как там это называется, где у файла хранится всякое и в том числе откуда он скачан) то все будет запускаться? Или локальное приложение имеется ввиду собранный на той-же машине хелловорлд подписанный в момент сборки?
1

Information

Rating
Does not participate
Registered
Activity