b00bl1k's homepagehttps://b00bl1k.ru/2023-12-31T00:00:00+03:00Status update, 20232023-12-31T00:00:00+03:002023-12-31T00:00:00+03:00Alexeytag:b00bl1k.ru,2023-12-31:/2023/12/31/Status-update-2023.html<p>Не сказать, что прошедший год оправдал ожидания, но, по крайней мере, не стало
хуже. Время будто застыло, события медленно переваливались одно за другим и в
итоге слились в одну кашу, которая вот-вот застынет и ложка в ней будет стоять
вертикально.</p>
<h2>Про привычки</h2>
<p>В прошедшем году я использовал немного доработанный
<a href="https://github.com/codito/habito">habito …</a></p><p>Не сказать, что прошедший год оправдал ожидания, но, по крайней мере, не стало
хуже. Время будто застыло, события медленно переваливались одно за другим и в
итоге слились в одну кашу, которая вот-вот застынет и ложка в ней будет стоять
вертикально.</p>
<h2>Про привычки</h2>
<p>В прошедшем году я использовал немного доработанный
<a href="https://github.com/codito/habito">habito</a> в качестве трекера привычек. Добавил
в него визуализацию данных на целый год: заполненный квадратик означает наличие
хоть какой-либо активности за конкретный день, а квадратик зеленого цвета означает,
что был достигнут необходимый минимум. Вот пример моих занятий по английскому
за 2023 год с целью минимум 60 минут в день:</p>
<p><img alt="habito tracker" src="https://b00bl1k.ru/assets/habito-calendar-2023-eng.png"></p>
<h2>Про проекты</h2>
<p>Не так много новостей про публичные проекты, гораздо больше было работы в приватных
репозиториях.</p>
<p>В библиотеку <a href="https://github.com/b00bl1k/uwan">uwan</a> была добавлена начальная
поддержка чипа sx126x, обработка нескольких MAC комманд и декодирование даунлинков.
Для проверки работоспособности было сделано тестовое устройство на базе stm32wle5,
в котором уже интергрирован этот радио чип.</p>
<p>В телеграм бот <a href="https://t.me/avtonomerbot">@avtonomerbot</a> была добавлена поддержка
проверки российских мотоциклетных номеров.</p>
<h2>Про железо</h2>
<p>Как и планировал, увеличил объем RAM до 16 GB на своём ThinkPad x270. Сейчас этого
достаточно для повседневных задач, и я даже ни разу не заметил использование swap.</p>
<p>Ещё одно приобретение по железу это покупка клавиатуры
<a href="https://www.keychron.com/pages/keychron-k3-wireless-mechanical-keyboard">Keychron K3</a>.
Простая механическая беспроводная клавиатура с оптическими свичами. Удобна в
использовании, приятный отклик и, конечно, множество вариантов подсветки
под любое настроение.</p>
<h2>Про генеалогию</h2>
<p>Порадовал владимирский архив <a href="https://vlarhiv.ru/">ГАВО</a>, который оцифровал
некоторое количество ревизских сказок по Ковровскому уезду, что позволило мне
быстро продвинуться до 1696 года по одной из ветвей. Эта информация принесла
некоторые сюрпризы, которые предстоит расследовать в будущем.</p>
<p>Пару лет назад обнаружил такой ресурс как
<a href="https://nashipredki.com/">nashipredki.com</a> и только недавно оценил его возможности.
Помимо хорошо структурированной информации по населённым пунктам, есть возможность
добавить записи из метрических книг, ревизских сказок. Хотя процесс достаточно
хлопотный и явно не стоит того, чтобы добавлять все записи подряд, но он точно
полезен для добавления записей по людями из других волостей и губерний. Таким
образом можно облегчить исследователям поиск их уехавших/переехавших предков.
А процесс подписки на НП, фамилии и даже архивы позволяет своевременно получить
уведомления об изменениях.</p>Status update, 20222022-12-31T00:00:00+03:002022-12-31T00:00:00+03:00Alexeytag:b00bl1k.ru,2022-12-31:/2022/12/31/Status-update-2022.html<p style="padding-bottom: 1rem; font-style: italic; text-align: right">
«Все войны прошлого и будущего идут коллективно нахуй»</p>
<h2>Про проекты</h2>
<p>Практически никакого развития не получила библиотека
<a href="https://github.com/b00bl1k/uwan">uwan</a>. Но с её помощью была
сделана прошивка для тестового устройства, сигнализирующего об открытии/закрытии
двери, и оно передало уже более 19 тысяч сообщений. В планах, как минимум, дописать
пример использования этой библиотеки и …</p><p style="padding-bottom: 1rem; font-style: italic; text-align: right">
«Все войны прошлого и будущего идут коллективно нахуй»</p>
<h2>Про проекты</h2>
<p>Практически никакого развития не получила библиотека
<a href="https://github.com/b00bl1k/uwan">uwan</a>. Но с её помощью была
сделана прошивка для тестового устройства, сигнализирующего об открытии/закрытии
двери, и оно передало уже более 19 тысяч сообщений. В планах, как минимум, дописать
пример использования этой библиотеки и нарастить функциональность.</p>
<p>В телеграм бот <a href="https://t.me/avtonomerbot">@avtonomerbot</a> была добавлена поддержка
двух новых запросов: информация о новых сериях региона и поиск по номеру
общественного транспорта.</p>
<p>Спустя 4 года, снова приложил руки к написанию драйвера последовательных портов
для kolibrios. Но <a href="https://board.kolibrios.org/viewtopic.php?p=78764#p78764">выложил</a>
только бинарники для тестирования. Надеюсь, что продолжу в следующем году.</p>
<p>Начал разрабатывать небольшое приложение Serial Port Toolkit - альтернативу
программе COM Port Toolkit. Выпустил первую версию
<a href="https://github.com/b00bl1k/sptk/releases/tag/v0.1.0">sptk 0.1.0</a>, в которой ещё
много чего не реализовано, но основную функцию - приём и передачу данных она
выполняет. В планах на будущий год довести до релиза 1.0.0 и, возможно, добавить
его в AUR.</p>
<p>Перевёл этот блог с jekyll на pelican с кастомной темой, позаимствованной у
<a href="https://drewdevault.com/">drewdevault.com</a> с небольшими изменениями.</p>
<h2>Про железо</h2>
<p>За неделю до объявления ебучей мобилизации в РФ я прикупил себе Б/У ноут Lenovo
ThinkPad x270 на замену стационарному ПК. И эта покупка оказалась очень кстати -
теперь этот ноут моя единственная "рабочая лошадка". Проблем с аппаратной
поддержкой не возникло, в archlinux всё работает без каких-либо проблем.
Единственное, что нужно сделать, так это увеличить объем RAM с 8 ГБ до 16 ГБ.</p>
<h2>Про генеалогию</h2>
<p>Главным событием оказался запуск
<a href="https://af.ivarh.ru/">электронного читального зала</a> Ивановского архива.
За небольшую почасовую оплату можно просматривать отсканированные изображения
архивных документов. Дел, которые меня интересовали было не так много, тем не
менее я написал небольшое расширение для браузера, чтобы можно было сохранять
изображения удобным способом. По сообщениям архива, в следующем году не
планируется оцифровка фонда 1164 и 94, которые меня интересуют.</p>
<p>Также я сосредоточился на более детальном наполнении своего генеалогического
древа в Gramps. Судя по <a href="https://forum.vgd.ru/3/138135/">опросу на vgd.ru</a> эта
программа не особо пользуется популярностью, а зря. У неё есть ряд важных
преимуществ, про которые я, возможно, напишу небольшую статью.</p>Год работы датчика температуры LoRaWAN2022-05-27T00:00:00+03:002022-05-27T00:00:00+03:00Alexeytag:b00bl1k.ru,2022-05-27:/2022/05/27/Lora-node-151-year-statistics.html<p>С момента установки <a href="https://b00bl1k.ru/2020/09/30/Lora-node-151.html">датчика</a> прошло
полтора года, но поскольку в работе прибора были перерывы, то я решил написать
пост с результатами только после года непрерывной работы и вот время пришло.</p>
<p><a href="https://b00bl1k.ru/assets/20220527-tekcell-discharge.png"><img alt="График разряда" src="https://b00bl1k.ru/assets/20220527-tekcell-discharge.png"></a></p>
<p>Примерно через 4 месяца после первой установки датчика, разрядилась батарея,
в морозное утро января. Источником питания служила относительно новая
<a href="https://www.chipdip.ru/product/sb-aa02-1-2aa">1 …</a></p><p>С момента установки <a href="https://b00bl1k.ru/2020/09/30/Lora-node-151.html">датчика</a> прошло
полтора года, но поскольку в работе прибора были перерывы, то я решил написать
пост с результатами только после года непрерывной работы и вот время пришло.</p>
<p><a href="https://b00bl1k.ru/assets/20220527-tekcell-discharge.png"><img alt="График разряда" src="https://b00bl1k.ru/assets/20220527-tekcell-discharge.png"></a></p>
<p>Примерно через 4 месяца после первой установки датчика, разрядилась батарея,
в морозное утро января. Источником питания служила относительно новая
<a href="https://www.chipdip.ru/product/sb-aa02-1-2aa">1/2 AA Tekcell 1200mAh</a>. На
графике отображено напряжение батареи (измерение производилось сразу
после передачи) и температура окружающей среды. Видна корреляция напряжения и
температуры.</p>
<p>Стоит напомнить, что ADR у датчика был отключен, а передача данных осуществлялась
на скорости DR0 (SF12 BW125). Таким образом отправка 4 байт занимала примерно 1319 мс.</p>
<p>В мае 2021 года я заменил батарею на
<a href="https://www.chipdip.ru/product0/8888101475">Saft LS 14500 CNA AA</a> номинальной
ёмкостью в 2600 mAh. Скорость передачи данных была настроена на DR5 (SF7 BW125),
после чего прибор снова был установлен на улице. В таком состоянии он
проработал год. Предлагаю взглянуть на графики:</p>
<p><a href="https://b00bl1k.ru/assets/20220527-calendar-heatmap.png"><img alt="heatmap" src="https://b00bl1k.ru/assets/20220527-calendar-heatmap.png"></a></p>
<p><a href="https://b00bl1k.ru/assets/20220527-saft-discharge.png"><img alt="discharge diagram" src="https://b00bl1k.ru/assets/20220527-saft-discharge.png"></a></p>
<p><a href="https://b00bl1k.ru/assets/20220527-signal-strength.png"><img alt="signal strength diagram" src="https://b00bl1k.ru/assets/20220527-signal-strength.png"></a></p>Тестирование загрузки изображений с помощью pytest-django2021-04-20T00:00:00+03:002021-04-20T00:00:00+03:00Alexeytag:b00bl1k.ru,2021-04-20:/2021/04/20/Test-image-uploading-with-pytest-django.html<p>Для начала напишем фикстуру, которая создаёт изображение для загрузки:</p>
<div class="highlight"><pre><span></span><code><span class="nd">@pytest</span><span class="o">.</span><span class="n">fixture</span><span class="p">(</span><span class="n">scope</span><span class="o">=</span><span class="s2">"session"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">image_file</span><span class="p">(</span><span class="n">tmpdir_factory</span><span class="p">):</span>
<span class="n">img</span> <span class="o">=</span> <span class="n">PilImage</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"RGB"</span><span class="p">,</span> <span class="p">(</span><span class="mi">640</span><span class="p">,</span> <span class="mi">480</span><span class="p">))</span>
<span class="n">fn</span> <span class="o">=</span> <span class="n">tmpdir_factory</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="s2">"data"</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">"img.jpg"</span><span class="p">)</span>
<span class="n">img</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">fn</span><span class="p">))</span>
<span class="k">return</span> <span class="n">fn</span>
</code></pre></div>
<p>Я использую <code>PIL</code> для создания подходящего изображения.</p>
<p>Далее приведён код, который тестирует загрузку изображения методом …</p><p>Для начала напишем фикстуру, которая создаёт изображение для загрузки:</p>
<div class="highlight"><pre><span></span><code><span class="nd">@pytest</span><span class="o">.</span><span class="n">fixture</span><span class="p">(</span><span class="n">scope</span><span class="o">=</span><span class="s2">"session"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">image_file</span><span class="p">(</span><span class="n">tmpdir_factory</span><span class="p">):</span>
<span class="n">img</span> <span class="o">=</span> <span class="n">PilImage</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"RGB"</span><span class="p">,</span> <span class="p">(</span><span class="mi">640</span><span class="p">,</span> <span class="mi">480</span><span class="p">))</span>
<span class="n">fn</span> <span class="o">=</span> <span class="n">tmpdir_factory</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="s2">"data"</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">"img.jpg"</span><span class="p">)</span>
<span class="n">img</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">fn</span><span class="p">))</span>
<span class="k">return</span> <span class="n">fn</span>
</code></pre></div>
<p>Я использую <code>PIL</code> для создания подходящего изображения.</p>
<p>Далее приведён код, который тестирует загрузку изображения методом POST:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">test_upload_image</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">image_file</span><span class="p">,</span> <span class="n">settings</span><span class="p">,</span> <span class="n">tmpdir</span><span class="p">):</span>
<span class="n">settings</span><span class="o">.</span><span class="n">MEDIA_ROOT</span> <span class="o">=</span> <span class="n">tmpdir</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">image_file</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">fp</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="p">{</span><span class="s2">"image"</span><span class="p">:</span> <span class="n">fp</span><span class="p">})</span>
<span class="k">assert</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">200</span>
</code></pre></div>
<p>Перед загрузкой файла изменяется значение <code>MEDIA_ROOT</code> на временный каталог.
Здесь использована стандартная pytest фикстура <code>tmpdir</code> и фикстура <code>settings</code> из
модуля <a href="https://github.com/pytest-dev/pytest-django">pytest-django</a>.</p>Датчик температуры LoRaWAN2020-09-30T00:00:00+03:002020-09-30T00:00:00+03:00Alexeytag:b00bl1k.ru,2020-09-30:/2020/09/30/Lora-node-151.html<p>За основу взят готовый модуль Heltec <a href="https://heltec.org/project/lora-node-151/">LoRa Node 151</a>.
Плата содержит микроконтроллер с низким потреблением STM32L151 и радио чип SX1276.</p>
<p><img alt="Тепловая карта в Grafana" src="https://b00bl1k.ru/assets/lora-node-temperature.png"></p>
<p>В качестве LoRaWAN библиотеки использован проект <a href="https://github.com/Lora-net/LoRaMac-node">LoRaMAC-node</a>.
Так же был написан модуль для работы с шиной 1-wire через uart и модуль для работы с датчиком DS18B20.</p>
<p>Из особенностей можно отметить …</p><p>За основу взят готовый модуль Heltec <a href="https://heltec.org/project/lora-node-151/">LoRa Node 151</a>.
Плата содержит микроконтроллер с низким потреблением STM32L151 и радио чип SX1276.</p>
<p><img alt="Тепловая карта в Grafana" src="https://b00bl1k.ru/assets/lora-node-temperature.png"></p>
<p>В качестве LoRaWAN библиотеки использован проект <a href="https://github.com/Lora-net/LoRaMac-node">LoRaMAC-node</a>.
Так же был написан модуль для работы с шиной 1-wire через uart и модуль для работы с датчиком DS18B20.</p>
<p>Из особенностей можно отметить, что на плате имеется транзисторный ключ <code>Vext control</code> для управления
питанием внешних устройств. Чем собственно и была запитана шина 1-wire.</p>
<p>Микроконтроллер позволяет измерить опорное напряжение АЦП, а поскольку он запитывается почти напрямую с батареи,
то это позволяет оценить заряд батареи (на самом деле нет, т.к. график заряда Li-SOCl2 весьма нелинеен).</p>
<p>Измеренное значение температуры модуль передаёт в виде сообщения без подтверждения, а упаковывает данные
в формате <a href="https://developers.mydevices.com/cayenne/docs/lora/#lora-cayenne-low-power-payload">LPP Cayenne</a>.
Получается всего 4 байта, например: <code>00 67 00 aa</code>, где:
* 0x00 - Channel
* 0x67 - Temperature Sensor
* 0x00 0xaa - Data</p>
<p>Выбор такого формата обсуловлен тем, что многие сервера поддерживают его декодинг "из коробки".</p>
<p>Данные о напряжении батареи запрашивает сам LoRaWAN сервер. Для этого он с некоторой периодичностью отправляет
команду <code>DevStatusReq</code> (см. <a href="https://lora-alliance.org/sites/default/files/2018-07/lorawan1.0.3.pdf">LoRaWAN™ 1.0.3 Specification</a>), а
в ответ прибор отправляет <code>DevStatusAns</code> с полями <code>Battery</code> и <code>Margin</code>. Причем отправляется не напряжение
батареи, а уровень заряда от 1 до 254.</p>
<p>Т.к. на приёмной стороне предпологалось использовать дешевый одноканальный (или двух) шлюз, то ADR был выключен
и список частот ограничен базовыми 868.9 и 869.1. Скорость передачи - DR0 (SF12 BW125).</p>
<p>Серверная часть - ChirpStack, с настроенной http и influxdb интеграцией. По http Genealogy.mdдекодированные данные принимает
python-скрипт и отправляет данные в сервис <a href="https://narodmon.ru/">narodmon.ru</a>.</p>
<p>Декодированный payload выглядит так:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">"data"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AGcAfQ=="</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"objectJSON"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{\\"</span><span class="kc">te</span><span class="err">mpera</span><span class="kc">ture</span><span class="err">Se</span><span class="kc">ns</span><span class="err">or\\</span><span class="s2">":{\\"</span><span class="mi">0</span><span class="err">\\</span><span class="s2">":12.5}}"</span>
<span class="p">}</span>
</code></pre></div>
<p>Данные из influxdb удобно просматривать с помощью Grafana и плагина heatmap
(результат на КДПВ).</p>Генеалогии пост2020-04-04T00:00:00+03:002020-04-04T00:00:00+03:00Alexeytag:b00bl1k.ru,2020-04-04:/2020/04/04/Genealogy.html<p>Выписки из архивов, в основном все данные по Ковровскому уезду Владимирской
губернии.</p>
<p><img alt="Ивановский областной архив" src="https://b00bl1k.ru/assets/20190916-gaio.jpg"></p>
<h2>Ивановский архив (ГАИО)</h2>
<ul>
<li><a href="https://docs.google.com/spreadsheets/d/1595p6Iqf2sxvcBfa9eCaSRd7_H9C3RZqL0DH5dyffiM/edit?usp=sharing">Выписки из метрических книг</a></li>
</ul>
<h2>Владимирский архив (ГАВО)</h2>
<ul>
<li><a href="https://docs.google.com/spreadsheets/d/13HQNWqe72K2JdFwK5LdXt-00fYfsEEwkxzqGw5NRVnM/edit?usp=sharing">Выписки из метрических книг</a></li>
<li><a href="https://docs.google.com/spreadsheets/d/1Nbfsk65uOdiyT9ecfO0n2BJDEO21wpfnv4j39HQAj0o/edit?usp=sharing">Выписки из исповедных ведомостей</a></li>
</ul>
<h2>Поиск захоронений</h2>
<p>Проект по поиску захоронений <a href="https://pogost.org">pogost.org</a></p>