Обработка источников климатических данных
Пользователь выбирает, какие климатические данные использовать для расчёта: климатический район здания, климатический район подстанции или собственные значения. Вкладка «Условия отопительного периода» переименовывается в «Климатические условия» и показывает все доступные наборы данных, включая широту. Широта с другими климатическими данными передаётся в InputModel и проверяется, при отсутствии формируется понятное сообщение в логе.
1. Источник (как есть)
При расчёте модели здания подстанции возникает ошибка:
Отсутствуют записи справочника солнечной радиации для стороны света
2. Разбор
2.1. От сообщения к причине
Сообщение верно и бесполезно: оно про следствие. Записей справочника нет потому, что они выбираются по широте, а широты нет. Широты может не быть:
- не указана в данных климатического района.
- не указан климатический район здания.
- здание является зданием подстанции, пользователь ожидает, что климатические данные будут определены по климатическому району подстанции.
В случаях 2 и 3 рядом появляется вторая ошибка: без климатического района нет и данных отопительного периода, они тоже приводятся к нулю, и секция te.heating_degree_days сообщает о выходе \(z_{ht}\) за границы диапазона. Две ошибки об одной причине, и ни одна её не называет.
Пользователь не может обнаружить причину и до расчёта: широта не выводится в интерфейсе нигде.
2.2. Целевой сценарий
Пользователю на UI надо показать какие справочные климатические данные есть и дать выбрать какие использовать в расчёте: данные климатического района здания, климатического района подстанции, на территории которой здание размещено, или по собственным данным.
Тем самым закрывается пункт «Поведение модели здания ПС, если Климатический район здания не определён» из CR 2026-08-19: доработки этапа 2, где предлагалась молчаливая подстановка района подстанции. Подстановки не будет: выбор виден на экране и хранится в модели.
2.3. Данные
Всё, что нужно, в БД уже есть, загрузка из АИС ОИА ПЭО правок не требует: ссылка на климатический район у Здание (сущность) и у Подстанция (сущность), собственная географическая широта подстанции, справочник Климатический район (сущность). Здание связано с подстанцией через организационный объект.
2.4. Широта
Широта — четвёртая величина набора, наравне с продолжительностью, температурой и скоростью ветра: она определяет выборку записей справочника солнечной радиации в секции te.solar_radiation_by_direction, тогда как остальные три входят в te.heating_degree_days.
Сейчас широта источнику не подчиняется: она всегда берётся из климатического района здания, независимо от выбранного источника условий ОП. То есть при выборе «Данные пользователя» температура и ветер берутся пользовательские, а солнечная радиация — по району здания, и пользователь этого не видит, потому что широты на экране нет. Широта должна определяться тем же источником, что и остальные три величины, показываться на UI и вносится пользователем, если источник - пользовательские данные.
Широта должна передаваться в модель входных данных расчёта. Сейчас она в неё не входит:
Маппинг домен → InputModel (ТЭ) прямо оговаривает, что широта
определяется вызывающей стороной и в InputModel не передаётся. Пока широта была
единственно возможной, это было допустимо; как только она становится предметом выбора,
расчёт не должен добирать её сам, минуя входную модель. Маппинг:
Параметр InputModel |
Характеристика Сервиса | Ед. изм. |
|---|---|---|
HeatingPeriod.Latitude (heatingPeriod.latitudeDeg) |
широта выбранного источника климатических данных | ° |
Оговорка в разделе TeInputSection.References снимается.
Пользовательская широта — целое число градусов, как и широта климатического района: записи справочника солнечной радиации ключуются целым градусом, дробное значение пришлось бы округлять, и расчёт шёл бы не по введённому пользователем значению.
2.5. Географическая широта подстанции — только для информации
Собственная широта подстанции ведётся строкой вида 55°5'47"N — градусы, минуты,
секунды, сторона света. Источником расчётных данных она быть не может: справочник
солнечной радиации ключуется целым градусом, а перевод строки в градусы — округление,
которое Сервис сделал бы молча.
На вкладку климатических условий она не выносится: там показываются данные, участвующие в расчёте. Своё место у неё уже есть — карточка подстанции (Карточка Подстанции), где она стоит рядом с широтой климатического района подстанции, и расхождение между ними видно там же.
2.6. Источник климатических данных
Справочник Источник условий ОП расширяется: прежнее значение «Справочные данные» расщепляется на «Климатический район здания» и «Климатический район подстанции». Существующие модели переводятся в «Климатический район здания» — их поведение не меняется.
Значение «Климатический район подстанции» доступно только для зданий, размещённых на территории подстанции. Для остальных зданий выбор — район здания или данные пользователя.
Значение по умолчанию при создании модели: первое что определено: климатический район здания, если он задан; иначе — климатический район подстанции, если здание размещено на территории подстанции.
2.7. Правила валидации
Проверяется полнота выбранного источника, и сообщается именно она: «в климатическом районе здания не задана широта», а не «нет записей справочника солнечной радиации». Правила вносятся в методику — в секции te.heating_degree_days и te.solar_radiation_by_direction, — где сейчас источником названы данные климатического района здания.
Отсутствующее значение не приводится к нулю. Это тот же дефект, что разобран в CR по четырёхскатным крышам на длине конька: подстановка правдоподобного числа вместо пустого значения теряет причину ошибки, а расчёт возвращает результат по другим данным.
2.8. Вкладка «Климатические условия»
Вкладка Вкладка "Климатические условия" переименовывается и получает третий набор данных — климатический район подстанции, доступный только для зданий, размещённых на её территории. Широта добавляется в каждый набор.
Механика выбора остаётся прежней: источник подменяет отображаемый блок данных. Виден набор, по которому ведётся расчёт, — этого достаточно, чтобы увидеть незаданную широту, а параллельный показ невыбранных наборов загромождал бы вкладку.
Незаполненное значение внутри показанного блока выводится прочерком, а не скрытой строкой: скрытая строка неотличима от отсутствующего поля, а именно из-за этого пользователь и не видел, что широта не задана.
Сущность Модель отопительного периода и секции методики не переименовываются: градусо-сутки остаются градусо-сутками отопительного периода. Переименование касается вкладки карточки модели.
2.9. Что остаётся как есть
Значение справочника «Фактические данные» (ActualClimateData) и три соответствующих
атрибута модели отопительного периода не трогаются, хотя из справочника значение
удалено миграцией: их судьба — отдельное решение, в объём этого CR не входит.
3. Blast radius
3.1. Спецификация
| Документ | Правка |
|---|---|
| Источник условий ОП | состав справочника: «Справочные данные» расщепляется на «Климатический район здания» и «Климатический район подстанции» |
| Модель отопительного периода | новый атрибут «Широта (данные пользователя)»; уточнение описания источника данных |
| te.heating_degree_days | источник \(z_{ht}\) и \(t_{ext}\) — выбранный источник климатических данных; правило полноты выбранного источника |
| te.solar_radiation_by_direction | внесено: широта \(φ\) в исходных данных секции — значение выбранного источника климатических данных; правила валидации широты (\(φ\) задана, \(φ \in [-90; 90]\)) и порядок проверки — широта до полноты справочника |
| Модель расчёта CalcModel | новое поле широты в модели входных данных |
| Маппинг домен → InputModel (ТЭ) | широта передаётся в InputModel; снимается оговорка «определяется вызывающей стороной» |
| Вкладка "Климатические условия" | переименование вкладки, набор данных климатического района подстанции, широта в каждом наборе, макет экрана |
| Карточка Здания | сверка: широта района здания в описании полей есть, в реализации не выводится |
| Карточка Подстанции | сверка: широта района подстанции и географическая широта |
3.2. База данных
CmHeatingPeriodConditionsSrc— новое значение перечисления и запись справочника; описание существующей записи уточняется до «климатического района здания».CmHeatingPeriodModelEntity— свойствоCustLatitude(int?) и сеттер по образцу соседних; копирование вCopy.- Миграция EF: колонка
cust_latitudeвntr.cm_heating_period_models; перевод существующих моделей с «Справочные данные» на «Климатический район здания». - Read-модель модели отопительного периода и её конфигурация.
3.3. API и контракты
HeatingPeriodModelDetailsи DTO вConsumptionModelDtos— новое поле.GetConsumptionModelForEditQueryHandler— проекция поля.CreateConsumptionModelCommandHandler— вычисление умолчания источника по данным здания и подстанции;ApplyConsumptionModelEditCommandHandler— запись значения.GetBuildingSummaryQuery— климатические данные района подстанции в ответе, чтобы вкладка могла показать этот набор.- Swagger-контракт меняется ⇒ перегенерация клиента фронтенда.
3.4. Расчёт
Цепочка: выбранный источник → значения набора (широта, продолжительность, температура,
ветер) → InputModel → секции te.heating_degree_days и
te.solar_radiation_by_direction.
CalcInputModelFactory— чтение климатического района подстанции;ResolveHeatingPeriodвозвращает четвёртую величину — широту — и различает два справочных источника; выборка солнечной радиации ведётся по разрешённой широте, а не по району здания.InputModel— поле широты;Ntr.Calc— приём широты из входной модели.- Валидация полноты выбранного источника с указанием причины.
3.5. Интерфейс
heating-period.util.ts— переименование вкладки, третий набор данных (район подстанции), широта в наборах, контрол пользовательской широты; механика подмены отображаемого блока по выбранному источнику остаётся прежней.building.util.ts,substation.util.ts— вывод широты; незаполненные значения показывать прочерком вместо скрытия строки (include: … != null).- Прототип: страница вкладки пересобирается по описанию полей.
3.6. Тесты
- Разрешение источника: район здания, район подстанции, данные пользователя.
- Умолчание при создании модели: район здания приоритетнее района подстанции.
- Валидация неполного выбранного источника — сообщается причина.
4. План
- Правки спецификации по таблице blast radius; в изменённых секциях проставить
StatusиCommentsсо ссылкой на этот CR. - Справочник источников, домен и БД: значение перечисления, атрибут, миграция с переводом существующих моделей, read-модель.
- API: контракты, умолчание при создании модели, климатические данные подстанции в ответе сводки по зданию; перегенерация клиента.
- Расчёт: разрешение источника с широтой, передача широты во входную модель, валидация полноты выбранного источника.
- UI: вкладка «Климатические условия», вывод широты в карточках здания и подстанции.
- Зафиксировать «Итог»; закрыть пункт 4 CR 2026-08-19 ссылкой на этот CR.
5. Acceptance criteria
- AC-1. На вкладке «Климатические условия» выбор источника подменяет отображаемый блок данных: показан набор выбранного источника, включая широту.
- AC-2. Незаполненное значение показанного набора выводится прочерком, а не скрытой строкой.
- AC-3. Источник «Климатический район подстанции» доступен в списке только для зданий, размещённых на территории подстанции.
- AC-4. При создании модели источник по умолчанию: климатический район здания, если он задан; иначе климатический район подстанции, если здание размещено на её территории.
- AC-5. Расчёт с источником «Климатический район подстанции» использует широту, продолжительность, температуру и скорость ветра района подстанции; с источником «Данные пользователя» — все четыре введённые пользователем величины, включая широту.
- AC-6. Если в выбранном источнике не заполнена величина, расчёт сообщает именно это — с указанием источника и величины, — а не отсутствие записей справочника солнечной радиации или выход \(z_{ht}\) за границы.
- AC-7. Существующие модели после миграции считаются с прежним результатом: источник «Климатический район здания».
6. Итог
—
Структурные связи
Использует
- Документ 2. Модель расчёта CalcModel
- Документ Маппинг доменных данных → InputModel (ТЭ)
- Доменная сущность Здание (сущность)
- Доменная сущность Источник условий ОП
- Доменная сущность Климатический район (сущность)
- Доменная сущность Модель отопительного периода
- Доменная сущность Подстанция (сущность)
- Запрос на изменение Доработки этапа 2 — список замечаний
- Компонент Вкладка "Климатические условия"
- Компонент Карточка Здания
- Компонент Карточка Подстанции
- Прикладной сервис Теплотехнический расчёт
Связанные артефакты
Документы
- Документ 2. Модель расчёта CalcModel
- Документ Маппинг доменных данных → InputModel (ТЭ)
- Доменная сущность Здание (сущность)
- Доменная сущность Источник условий ОП
- Доменная сущность Климатический район (сущность)
- Доменная сущность Модель отопительного периода
- Доменная сущность Подстанция (сущность)
- Запрос на изменение Доработки этапа 2 — список замечаний
- Компонент Вкладка "Климатические условия"
- Компонент Карточка Здания
- Компонент Карточка Подстанции