{
    "version": "https:\/\/jsonfeed.org\/version\/1.1",
    "title": "Блоги: заметки с тегом скрипт",
    "_rss_description": "Автоматически собираемая лента заметок, написанных в блогах на Эгее",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": false,
    "_itunes_explicit": "no",
    "home_page_url": "https:\/\/blogengine.ru\/blogs\/tags\/skript\/",
    "feed_url": "https:\/\/blogengine.ru\/blogs\/tags\/skript\/json\/",
    "icon": false,
    "authors": [
        {
            "name": "Илья Бирман",
            "url": "https:\/\/blogengine.ru\/blogs\/",
            "avatar": false
        }
    ],
    "items": [
        {
            "id": "134734",
            "url": "https:\/\/kini24.ru\/all\/poluchaem-dannye-s-sayta-sgk-dlya-home-assistant\/",
            "title": "Получаем данные с сайта СГК для Home Assistant",
            "content_html": "<p>В Home Assistant у меня было отслеживание почти всех счетов по квартире: электроэнергия, коммунальные платежи, ТКО, капитальный ремонт и т. д. Проблема была только с сайтом компании СГК, которая занимается предоставлением горячей и холодной воды, отоплением и водоотведением. При помощи таких интеграций, как scrape и multiscrape загрузить данные с их сайта не получалось, поэтому пришлось пойти более сложным путем и написать свой скрипт. На деле он оказался совсем простым, требует доработки в плане проверок ответов сервера, но даже в таком виде он вполне работоспособен. Чтобы не перечислять все данные, возьму только отопление.<\/p>\n<code python>\nimport requests\nimport json\n\nlogin = data.get(\"username\", \"\")\npassword = data.get(\"password\", \"\")\nlogin_url = 'https:\/\/krk.sibgenco.services\/Account\/Auth'\ndata_url = 'https:\/\/krk.sibgenco.services\/fl\/accounts\/getAccounts'\n\nheaders = {\n    \"Content-Type\": \"application\/x-www-form-urlencoded; charset=UTF-8\",\n    \"User-Agent\": \"Mozilla\/5.0 (Windows NT 6.1; Win64; x64; rv:109.0) Gecko\/20100101 Firefox\/115.0\",\n}\n\n# Создаем новую сессию\nsession = requests.Session()\n# Авторизуемся на сервере\nresult = session.post(login_url, data = 'login=' + login + '&password=' + password, headers = headers)\n# print(result.text)\n\n# Получаем данные в JSON формате\nresult = session.get(data_url, headers = headers).json()\nsession.close()\n\n# Перекодируем текст в читаемый\nresult = result.encode().decode('unicode-escape', 'ignore')\nresult = json.dumps(result)\nresult = json.loads(result)\n\n# Убираем лишние кавычки в разделе \"Cards\" (откуда взялись?)\nresult = result.replace('\"Cards\":\"', '\"Cards\":').replace('}]\"}', '}]}')\n# print(type(result))\n# print(result)\n\nif len(result) > 0:\n    logger.info(\"Данные от СКГ получены\")\nelse:\n    logger.warning(\"Ошибка получения данных от СГК\")\n# print(result.encode().decode('unicode-escape', 'ignore'))\n\n# Преобразуем строку данных в JSON объект\njson_data = json.loads(result)[\"Accounts\"][0][\"CalcData\"][\"Products\"]#[0][\"ToPay\"]\n\n# print(json_data, '\\n')\n# print(json.dumps(json_data), '\\n')\n\n# for product in json_data[\"Accounts\"][0][\"CalcData\"][\"Products\"]:\n#     print(product[\"ItemName\"] + \": \" + str(product[\"ToPay\"]) + \" руб.\")\n\nif json_data[0][\"ToPay\"] > 0:\n    hass.states.set('sensor.sgk_heating', json_data[0][\"ToPay\"] * -1)\nelse:\n    hass.states.set('sensor.sgk_heating', json_data[0][\"ToPay\"])\n<\/code>\n<p>В ходе работы скрипта получаем несколько секций для каждой из услуг, которые выглядят вот так:<\/p>\n<code json>\n  - IsFine: false\n    Item: 13\n    ContractId: 307015\n    ItemName: Отопление\n    SaldoBegin: 4228.65\n    Paid: 4228.65\n    SaldoEnd: 0\n    FineEndCheck: true\n    FineEnd: 0\n    AccrualsCheck: false\n    Accruals: 0\n    Recalculation: 0\n    ToPayCheck: true\n    ToPay: 0\n    ChargeDetails: \"\"\n    PayDetails: 08.02.2025 4228.65;\n    FinePayDetails: \"\"\n    WebPayDetails: 08.02.2025=5338.65=20250208171312-99240-6764617.585349\n<\/code>\n<p>Далее просто создаем автоматизацию в Home Assistant, которая будет запускать этот скрипт. Для надежности перед первым запуском создаем несколько новых сенсоров в примерно таком формате:<\/p>\n<code python>\n    # Задолженность за отопление, итого\n    heating_debt_summary:\n      unique_id: <тут ваш ID сенсора>\n      attribute_templates:\n        Пеня: \"{{ states('sensor.sgk_heating_penya') }} ₽\"\n      device_class: monetary\n      friendly_name: Задолженность за отопление\n      unit_of_measurement: \"RUB\"\n      # value_template: \"{{ states('sensor.sgk_heating') | float(0) + states('sensor.sgk_heating_penya') | float(0) }}\"\n      value_template: \"{{ states('sensor.sgk_heating') | float(0) }}\"\n<\/code>\n<p>Как видно, в сенсоре будет также атрибут «пеня». Можно вывести суммарную задолженность — долг+пеня, можно вывести только основную — на выбор.<br \/>\nИ вот после сайта СГК меня слегка «понесло» и сделал схожие скрипты для получения информации с сайтов ФНС, капремонта, энергосбыта и регистратора доменов. С ФНС было интересно — там сначала нужно пройти basic-авторизацию, получить токен безопасности, авторизоваться еще раз и слать его при каждом запросе данных. А дальше было уже намного легче — у ФНС существует API, которое они активно используют. Официальной документации по нему нет, но, покопавшись на сайте, можно легко получить все запросы. Для чего нужны эти данные? Например, чтобы отслеживать задолженность по налогам (в том числе и самозанятого), недвижимость и банковские счета. Сейчас такое время, что на тебя могут открыть какой-то счет в банке, сделать тебя «начальником» какой-то конторы, а ты даже будешь не в курсе. Но стоит отметить, что в налоговой отображаются только обычные, дебетовые счета, информации по кредитам там нет.<\/p>\n",
            "date_published": "2025-02-20T08:22:01+05:00",
            "date_modified": "2025-03-27T09:18:56+05:00",
            "tags": [
                "home assistant",
                "python",
                "Вода",
                "данные",
                "налоговая",
                "отопление",
                "получение",
                "Сайт",
                "сгк",
                "скрипт"
            ],
            "author": {
                "name": "Копытов Иван",
                "url": "https:\/\/kini24.ru\/",
                "avatar": ""
            },
            "_date_published_rfc2822": "Thu, 20 Feb 2025 08:22:01 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "134734",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": null,
                "og_images": []
            }
        },
        {
            "id": "124968",
            "url": "https:\/\/kini24.ru\/all\/obnovlenie-wildcard-sertifikatov-letsencrypt\/",
            "title": "Обновление wildcard-сертификатов Let’sEncrypt",
            "content_html": "<h3>Случай, когда ваш домен располагается на reg.ru<\/h3>\n<p>Можно, конечно, воспользоваться сторонними библиотеками, но я не любитель ставить что-то стороннее, если можно обойтись своими силами. Поэтому пришлось потратить время на написание и тестирование bash-скрипта с именем authenticator.sh:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">#!\/bin\/bash\r\n\r\n#Основные параметры\r\ndomain=&quot;kini24.ru&quot;\r\nusername=&quot;graywolf&quot;\r\npassword=&quot;********&quot;\r\n# Этот параметр менять не нужно\r\nsubdomain=&quot;&quot;\r\n\r\n# Корректно задаем судбдомен\r\n# Если обрабатывается основной домен, то субдомен будет _acme-challenge\r\n# Если обрабатывается субдомен, то строка будет вида _acme-challenge.subdomain\r\nif [[ $CERTBOT_DOMAIN = $domain ]]\r\nthen\r\n  subdomain=&quot;_acme-challenge&quot;\r\nelse\r\n  subdomain=&quot;_acme-challenge.${CERTBOT_DOMAIN%.$domain}&quot;\r\nfi\r\n\r\n# Чисто для информации\r\n\/usr\/bin\/echo &quot;Requesting $CERTBOT_DOMAIN&quot;\r\n\r\n# Запрос на удаления текущих записей\r\ntxt_delete=&quot;input_format=json&amp;input_data={\\&quot;username\\&quot;:\\&quot;$username\\&quot;,\\&quot;password\\&quot;:\\&quot;$password\\&quot;,\\&quot;domains\\&quot;:[{\\&quot;dname\\&quot;:\\&quot;$domain\\&quot;}],\\&quot;subdomain\\&quot;:\\&quot;$subdomain\\&quot;,\\&quot;record_type\\&quot;:\\&quot;TXT\\&quot;,\\&quot;output_content_type\\&quot;:\\&quot;plain\\&quot;}&quot;\r\n\r\n# Запрос на добавления записи\r\ntxt_add=&quot;input_format=json&amp;input_data={\\&quot;username\\&quot;:\\&quot;$username\\&quot;,\\&quot;password\\&quot;:\\&quot;$password\\&quot;,\\&quot;domains\\&quot;:[{\\&quot;dname\\&quot;:\\&quot;$domain\\&quot;}],\\&quot;subdomain\\&quot;:\\&quot;$subdomain\\&quot;,\\&quot;text\\&quot;:\\&quot;$CERTBOT_VALIDATION\\&quot;,\\&quot;output_content_type\\&quot;:\\&quot;plain\\&quot;}&quot;\r\n\r\n#Можно проверить при желении\r\n#\/usr\/bin\/echo &quot;Certbot parameters:&quot;\r\n#\/usr\/bin\/echo &quot;Current domain: $CERTBOT_DOMAIN&quot;\r\n\/usr\/bin\/echo &quot;Validation string: $CERTBOT_VALIDATION&quot;\r\n#\/usr\/bin\/echo &quot;Delete request: $txt_delete&quot;\r\n#\/usr\/bin\/echo &quot;Add request: $txt_add&quot;\r\n\r\n# Запрос на удаление ВСЕХ TXT записей\r\nif [[ $CERTBOT_DOMAIN != $domain ]]\r\nthen\r\n #\/usr\/bin\/echo &quot;Remove all TXT records&quot;\r\n  \/usr\/bin\/curl --silent --data &quot;$txt_delete&quot; &quot;https:\/\/api.reg.ru\/api\/regru2\/zone\/remove_record&quot;\r\nfi\r\n\r\n# Запрос на создание TXT записи\r\n#\/usr\/bin\/echo &quot;Add new TXT record&quot;\r\n\/usr\/bin\/curl --silent --data &quot;$txt_add&quot; &quot;https:\/\/api.reg.ru\/api\/regru2\/zone\/add_txt&quot;\r\n\r\n# Проверяем что нужная TXT запись появилась. Иначе ждем пока данные обновятся\r\n#answer=&quot;&quot;\r\n#while [[ $answer != $CERTBOT_VALIDATION ]]\r\n#do\r\n#  \/usr\/bin\/echo &quot;Requesting DNS record&quot;\r\n#  answer=$(\/usr\/bin\/dig @77.88.8.8 $CERTBOT_DOMAIN txt +short | \/usr\/bin\/tr -d \\&quot; | \/usr\/bin\/egrep $CERTBOT_VALIDATION)\r\n#  \/usr\/bin\/sleep 60\r\n#done\r\n\r\nif [[ $CERTBOT_REMAINING_CHALLENGES -eq 0 ]]\r\nthen\r\n  sleep 15m\r\nfi\r\n\r\n# Выводим количество доменов, которые осталось обработать\r\n\/usr\/bin\/echo &quot;Remaining challenges: $CERTBOT_REMAINING_CHALLENGES&quot;<\/code><\/pre><p>Логика скрипта следующая. В начале задаются основной домен, имя пользователя и пароль от личного кабинета reg.ru. Параметр <i>subdomain<\/i> менять не нужно, он «вычисляется» по ходу выполнения скрипта. Далее если обрабатывается основной домен, то поддомен становится равным <i>_acme-challenge<\/i>, иначе в конец еще добавляется поддомен. Формируется строка для удаления всех (!) текущих записей типа TXT, если обрабатыается поддомен. Записи для основного домена просто добавляются (тут да, небольшой косяк, нужно немного дописать скрипт).<br \/>\nЗатем, после добавления DNS-записи скрипт должен был запрашивать все записи TXT и, после появлении нужной, продолжать выполнение, но тут скрипт уходил в бесконечный цикл, поэтому я его закомментировал полностью. Сможете исправить — буду благодарен.<br \/>\nНа последнем шаге скрипт, если доменов для регистрации не осталось, ждет 15 минут (время обновления записей у reg.ru от 15 минут до 1 часа) и возвращает управление команде certbot.<\/p>\n<p>Вызывается скрипт примерной такой командой:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">certbot certonly --manual --agree-tos --manual-public-ip-logging-ok --email admin@kini24.ru --preferred-challenges dns --server https:\/\/acme-v02.api.letsencrypt.org\/directory --domain *.jabber.kini24.ru --domain *.meet.kini24.ru --domain *.kini24.ru --domain kini24.ru --rsa-key-size 2048 --key-type ecdsa --elliptic-curve secp256r1 --redirect --uir --staple-ocsp --must-staple --hsts --manual-auth-hook \/root\/authenticator.sh<\/code><\/pre><p>В этой команде следующие параметры:<br \/>\n<i>certonly<\/i> — только получение сертификата;<br \/>\n<i>agree-tos<\/i> — принимаем пользовательское соглашение;<br \/>\n<i>manual-public-ip-logging-ok<\/i> — соглашаемся на публикацию нашего IP-адреса;<br \/>\n<i>email<\/i> — указываем свою электронную почту для уведомлений;<br \/>\n<i>preferred-challenges<\/i> — выбираем тип проверки. Для wildcard-сертификатов это только DNS;<br \/>\n<i>server<\/i> — указываем сервер сертификации;<br \/>\n<i>domain<\/i> — перечисляем свои (суб-)домены;<br \/>\n<i>rsa-key-size<\/i> — указываем «размер» ключа. Значение 2048 по умолчанию, оставил на всякий случай;<br \/>\n<i>key-type<\/i> — тип ключа. Снова указано значение по умолчанию;<br \/>\n<i>elliptic-curve<\/i> — «кривые». Тут тоже значение по умолчанию;<br \/>\n<i>redirect<\/i> — перенаправлять с http на https$<br \/>\n<i>uir<\/i> — добавляет в ответ заголовок <i>Content-Security-Policy<\/i> со значением <i>upgrade-insecure-requests<\/i>;<br \/>\n<i>staple-ocsp<\/i> — «сшивание» сертификатов;<br \/>\n<i>must-staple<\/i> — обязательное «сшивание»;<br \/>\n<i>hsts<\/i> — принудительная активация защищенного режима, т. е. https;<br \/>\n<i>manual-auth-hook<\/i> — запуск своего скрипта.<\/p>\n",
            "date_published": "2023-12-16T14:16:55+05:00",
            "date_modified": "2023-12-16T14:16:15+05:00",
            "tags": [
                "reg.ru",
                "wildcard",
                "автоматическое",
                "обновление",
                "рег.ру",
                "сертификат",
                "скрипт"
            ],
            "author": {
                "name": "Копытов Иван",
                "url": "https:\/\/kini24.ru\/",
                "avatar": ""
            },
            "_date_published_rfc2822": "Sat, 16 Dec 2023 14:16:55 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "124968",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": null,
                "og_images": []
            }
        }
    ],
    "_e2_version": 4079,
    "_e2_ua_string": "Aegea 11.0 (v4079e)"
}