DmitrMakeev commited on
Commit
9eede58
·
verified ·
1 Parent(s): d98e04e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +115 -306
app.py CHANGED
@@ -756,156 +756,39 @@ NUTRIENT_CONTENT_IN_FERTILIZERS = {
756
 
757
 
758
 
759
-
760
-
761
- from tabulate import tabulate
762
-
763
- # Константы
764
- TOTAL_NITROGEN = 125.000
765
- NO3_RATIO = 8.25
766
- NH4_RATIO = 1.00
767
- VOLUME_LITERS = 100
768
-
769
- # Коэффициенты электропроводности
770
- EC_COEFFICIENTS = {
771
- 'P': 0.0012, 'K': 0.0018, 'Mg': 0.0015,
772
- 'Ca': 0.0016, 'S': 0.0014,
773
- 'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
774
- }
775
-
776
- # Целевые значения
777
- BASE_PROFILE = {
778
- 'P': 31.000, 'K': 210.000, 'Mg': 24.000,
779
- 'Ca': 84.000, 'S': 56.439,
780
- 'N (NO3-)': 0, 'N (NH4+)': 0
781
- }
782
-
783
- NUTRIENT_CONTENT_IN_FERTILIZERS = {
784
- "Кальциевая селитра": {"N (NO3-)": 0.11863, "Ca": 0.16972},
785
- "Калий азотнокислый": {"N (NO3-)": 0.136, "K": 0.382},
786
- "Калий сернокислый": {"K": 0.44874, "S": 0.18401},
787
- "Аммоний азотнокислый": {"N (NO3-)": 0.17499, "N (NH4+)": 0.17499},
788
- "Сульфат магния": {"Mg": 0.09861, "S": 0.13010},
789
- "Монофосфат калия": {"P": 0.218, "K": 0.275}
790
- }
791
-
792
-
793
- # Коэффициенты электропроводности
794
- EC_COEFFICIENTS = {
795
- 'P': 0.0012, 'K': 0.0018, 'Mg': 0.0015,
796
- 'Ca': 0.0016, 'S': 0.0014,
797
- 'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
798
- }
799
-
800
- # Целевые значения
801
- BASE_PROFILE = {
802
- 'P': 31.000, 'K': 210.000, 'Mg': 24.000,
803
- 'Ca': 84.000, 'S': 56.439,
804
- 'N (NO3-)': 0, 'N (NH4+)': 0
805
- }
806
-
807
- NUTRIENT_CONTENT_IN_FERTILIZERS = {
808
- "Кальциевая селитра": {"N (NO3-)": 0.11863, "Ca": 0.16972},
809
- "Калий азотнокислый": {"N (NO3-)": 0.136, "K": 0.382},
810
- "Калий сернокислый": {"K": 0.44874, "S": 0.18401},
811
- "Аммоний азотнокислый": {"N (NO3-)": 0.17499, "N (NH4+)": 0.17499},
812
- "Сульфат магния": {"Mg": 0.09861, "S": 0.13010},
813
- "Монофосфат калия": {"P": 0.218, "K": 0.275}
814
- }
815
-
816
-
817
-
818
-
819
-
820
- from tabulate import tabulate
821
-
822
- # Константы
823
- TOTAL_NITROGEN = 125.000
824
- NO3_RATIO = 8.25
825
- NH4_RATIO = 1.00
826
- VOLUME_LITERS = 100
827
-
828
- # Коэффициенты электропроводности
829
- EC_COEFFICIENTS = {
830
- 'P': 0.0012, 'K': 0.0018, 'Mg': 0.0015,
831
- 'Ca': 0.0016, 'S': 0.0014,
832
- 'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
833
- }
834
-
835
- # Целевые значения
836
- BASE_PROFILE = {
837
- 'P': 31.000, 'K': 210.000, 'Mg': 24.000,
838
- 'Ca': 84.000, 'S': 56.439,
839
- 'N (NO3-)': 0, 'N (NH4+)': 0
840
- }
841
-
842
- NUTRIENT_CONTENT_IN_FERTILIZERS = {
843
- "Кальциевая селитра": {"N (NO3-)": 0.11863, "Ca": 0.16972},
844
- "Калий азотнокислый": {"N (NO3-)": 0.136, "K": 0.382},
845
- "Калий сернокислый": {"K": 0.44874, "S": 0.18401},
846
- "Аммоний азотнокислый": {"N (NO3-)": 0.17499, "N (NH4+)": 0.17499},
847
- "Сульфат магния": {"Mg": 0.09861, "S": 0.13010},
848
- "Монофосфат калия": {"P": 0.218, "K": 0.275}
849
- }
850
-
851
  class NutrientCalculator:
852
  def __init__(self, volume_liters=1.0):
853
  self.volume = volume_liters
854
  self.results = {}
855
- self.target_profile = BASE_PROFILE.copy()
856
- self.actual_profile = {k: 0.0 for k in BASE_PROFILE}
857
- self.fertilizers = NUTRIENT_CONTENT_IN_FERTILIZERS
858
  self.total_ec = 0.0
859
 
860
- # Расчёт азота
861
- total_parts = NO3_RATIO + NH4_RATIO
862
- self.target_profile['N (NO3-)'] = TOTAL_NITROGEN * (NO3_RATIO / total_parts)
863
- self.target_profile['N (NH4+)'] = TOTAL_NITROGEN * (NH4_RATIO / total_parts)
864
- self.initial_n_profile = {
865
- "NO3-": self.target_profile['N (NO3-)'],
866
- "NH4+": self.target_profile['N (NH4+)']
867
  }
868
 
869
  def _label(self, element):
870
- """Форматирование названий элементов для вывода"""
871
  labels = {
872
  'N (NO3-)': 'NO3',
873
  'N (NH4+)': 'NH4'
874
  }
875
  return labels.get(element, element)
876
 
877
- def calculate(self):
878
- try:
879
- self._apply("Сульфат магния", "Mg", self.target_profile['Mg'])
880
- self._apply("Кальциевая селитра", "Ca", self.target_profile['Ca'])
881
- self._apply("Монофосфат калия", "P", self.target_profile['P'])
882
- self._apply("Аммоний азотнокислый", "N (NH4+)", self.target_profile['N (NH4+)'])
883
-
884
- current_no3 = self.actual_profile['N (NO3-)']
885
- no3_needed = self.target_profile['N (NO3-)'] - current_no3
886
-
887
- if no3_needed > 0.1:
888
- self._apply("Калий азотнокислый", "N (NO3-)", no3_needed)
889
-
890
- self._apply_k_sulfate()
891
-
892
- k_deficit = self.target_profile['K'] - self.actual_profile['K']
893
- if k_deficit > 0.1:
894
- self._apply("Калий азотнокислый", "K", k_deficit)
895
-
896
- return self.results
897
- except Exception as e:
898
- print(f"Ошибка при расчёте: {str(e)}")
899
- raise
900
-
901
  def _apply(self, fert_name, main_element, required_ppm):
902
  if required_ppm <= 0:
903
  return
904
-
905
  try:
906
- content = self.fertilizers[fert_name][main_element]
 
 
 
907
  grams = (required_ppm * self.volume) / (content * 1000)
908
-
909
  if fert_name not in self.results:
910
  result = {
911
  'граммы': 0.0,
@@ -915,226 +798,150 @@ class NutrientCalculator:
915
  for element in self.fertilizers[fert_name]:
916
  result[f'внесет {self._label(element)}'] = 0.0
917
  self.results[fert_name] = result
918
-
919
  self.results[fert_name]['граммы'] += grams
920
- self.results[fert_name]['миллиграммы'] += int(grams * 1000)
921
-
922
  fert_ec = 0.0
923
  for element, percent in self.fertilizers[fert_name].items():
924
  added_ppm = (grams * percent * 1000) / self.volume
925
  self.results[fert_name][f'внесет {self._label(element)}'] += added_ppm
926
- self.actual_profile[element] += added_ppm
927
- fert_ec += added_ppm * EC_COEFFICIENTS.get(element, 0.0015)
928
-
929
  self.results[fert_name]['вклад в EC'] += fert_ec
930
  self.total_ec += fert_ec
931
  except KeyError as e:
932
- print(f"Ошибка: отсутствует элемент {str(e)} в удобрении {fert_name}")
933
  raise
934
 
935
- def _apply_k_sulfate(self):
936
- fert = "Калий сернокислый"
937
- k_def = self.target_profile['K'] - self.actual_profile['K']
938
- s_def = self.target_profile['S'] - self.actual_profile['S']
939
-
940
- if k_def <= 0 and s_def <= 0:
941
  return
942
-
943
- try:
944
- if s_def > 0.1:
945
- s_content = self.fertilizers[fert]["S"]
946
- grams_s = (s_def * self.volume) / (s_content * 1000)
947
-
948
- k_content = self.fertilizers[fert]["K"]
949
- k_from_s = (grams_s * k_content * 1000) / self.volume
950
-
951
- if k_from_s > k_def and k_def > 0.1:
952
- grams = (k_def * self.volume) / (k_content * 1000)
953
- else:
954
- grams = grams_s
955
-
956
- self._apply(fert, "S", s_def)
957
- except Exception as e:
958
- print(f"Ошибка при расчёте сульфата калия: {str(e)}")
959
- raise
960
-
961
- def calculate_ec(self):
962
- return round(self.total_ec, 2)
963
 
964
- def print_report(self):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
965
  try:
966
- print("\n" + "="*60)
967
- print("ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА (ИТОГО):")
968
- print("="*60)
969
- table = [[el, round(self.actual_profile[el], 1)] for el in self.actual_profile]
970
- print(tabulate(table, headers=["Элемент", "ppm"]))
971
-
972
- print("\nИсходный расчёт азота:")
973
- for form, val in self.initial_n_profile.items():
974
- print(f" {form}: {round(val, 1)} ppm")
975
-
976
- print("\n" + "="*60)
977
- print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
978
- print("="*60)
979
- print(f"Общая концентрация: {round(sum(self.actual_profile.values()), 1)} ppm")
980
- print(f"EC: {self.calculate_ec()} mS/cm")
981
-
982
- print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
983
- fert_table = []
984
- for fert, data in self.results.items():
985
- adds = [f"+{k}: {v:.1f} ppm" for k, v in data.items() if k.startswith('внесет')]
986
- fert_table.append([
987
- fert,
988
- round(data['граммы'], 3),
989
- data['миллиграммы'],
990
- round(data['вклад в EC'], 3),
991
- "\n".join(adds)
992
- ])
993
- print(tabulate(fert_table,
994
- headers=["Удобрение", "Граммы", "Миллиграммы", "EC (мСм/см)", "Добавит"]))
995
-
996
- print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
997
- deficit = {
998
- k: round(self.target_profile[k] - self.actual_profile[k], 1)
999
- for k in self.target_profile
1000
- if abs(self.target_profile[k] - self.actual_profile[k]) > 0.1
1001
- }
1002
- if deficit:
1003
- for el, val in deficit.items():
1004
- print(f" {el}: {val} ppm")
1005
- else:
1006
- print(" Все элементы покрыты полностью")
1007
- except Exception as e:
1008
- print(f"Ошибка при выводе отчёта: {str(e)}")
1009
- raise
1010
-
1011
- if __name__ == "__main__":
1012
- try:
1013
- calculator = NutrientCalculator(volume_liters=VOLUME_LITERS)
1014
- calculator.calculate()
1015
- calculator.print_report() # Правильный вызов метода класса
1016
- except Exception as e:
1017
- print(f"Критическая ошибка: {str(e)}")
1018
-
1019
 
 
 
1020
 
 
 
1021
 
 
 
1022
 
 
 
1023
 
 
 
1024
 
 
 
1025
 
 
 
 
 
1026
 
1027
 
1028
-
1029
- from flask import request, jsonify
1030
-
1031
- def round_floats(obj, ndigits=3):
1032
- """Рекурсивно округляет все float значения в структуре данных"""
1033
- if isinstance(obj, float):
1034
- return round(obj, ndigits)
1035
- elif isinstance(obj, dict):
1036
- return {k: round_floats(v, ndigits) for k, v in obj.items()}
1037
- elif isinstance(obj, (list, tuple)):
1038
- return [round_floats(x, ndigits) for x in obj]
1039
- return obj
1040
-
1041
  @app.route('/calculation', methods=['POST'])
1042
  def handle_calculation():
1043
  try:
1044
  data = request.get_json()
1045
-
1046
- # Получаем параметр точности округления (по умолчанию 3)
1047
- rounding_precision = int(data['profileSettings'].get('rounding_precision', 3))
1048
-
1049
  # Проверка обязательных полей
1050
  if not data or 'fertilizerConstants' not in data or 'profileSettings' not in data:
1051
  return jsonify({'error': 'Неверный формат данных'}), 400
1052
-
1053
- # Извлекаем данные из запроса
1054
- fertilizer_data = data['fertilizerConstants']
1055
- profile_data = data['profileSettings']
1056
-
1057
- # Устанавливаем константы из запроса
1058
- TOTAL_NITROGEN = float(profile_data.get('TOTAL_NITROG', 125.0))
1059
- NO3_RATIO = float(profile_data.get('NO3_RAT', 8.25))
1060
- VOLUME_LITERS = float(profile_data.get('liters', 100))
1061
- NH4_RATIO = 1.00 # Фиксированное значение
1062
-
1063
- # Формируем целевой профиль
1064
- target_profile = {
1065
- 'P': float(profile_data.get('P', 31.0)),
1066
- 'K': float(profile_data.get('K', 210.0)),
1067
- 'Mg': float(profile_data.get('Mg', 24.0)),
1068
- 'Ca': float(profile_data.get('Ca', 84.0)),
1069
- 'S': float(profile_data.get('S', 56.439)),
1070
- 'N (NO3-)': 0, # Будет рассчитано в калькуляторе
1071
- 'N (NH4+)': 0 # Будет рассчитано в калькуляторе
1072
- }
1073
-
1074
- # Обновляем константы удобрений
1075
- NUTRIENT_CONTENT_IN_FERTILIZERS = {
1076
  "Кальциевая селитра": {
1077
- "N (NO3-)": float(fertilizer_data["Кальциевая селитра"].get("N (NO3-)", 0.11863)),
1078
- "Ca": float(fertilizer_data["Кальциевая селитра"].get("Ca", 0.16972))
1079
  },
1080
  "Калий азотнокислый": {
1081
- "N (NO3-)": float(fertilizer_data["Калий азотнокислый"].get("N (NO3-)", 0.13854)),
1082
- "K": float(fertilizer_data["Калий азотнокислый"].get("K", 0.36672))
1083
  },
1084
  "Аммоний азотнокислый": {
1085
- "N (NO3-)": float(fertilizer_data["Аммоний азотнокислый"].get("N (NO3-)", 0.17499)),
1086
- "N (NH4+)": float(fertilizer_data["Аммоний азотнокислый"].get("N (NH4+)", 0.17499))
1087
  },
1088
  "Сульфат магния": {
1089
- "Mg": float(fertilizer_data["Сульфат магния"].get("Mg", 0.1022)),
1090
- "S": float(fertilizer_data["Сульфат магния"].get("S", 0.13483))
1091
  },
1092
  "Монофосфат калия": {
1093
- "P": float(fertilizer_data["Монофосфат калия"].get("P", 0.22761)),
1094
- "K": float(fertilizer_data["Монофосфат калия"].get("K", 0.28731))
1095
  },
1096
  "Калий сернокислый": {
1097
- "K": float(fertilizer_data["Калий сернокислый"].get("K", 0.44874)),
1098
- "S": float(fertilizer_data["Калий сернокислый"].get("S", 0.18401))
1099
  }
1100
  }
1101
-
1102
- # Создаем и настраиваем калькулятор
1103
- calculator = NutrientCalculator(volume_liters=VOLUME_LITERS)
1104
- calculator.target_profile = target_profile
1105
- calculator.fertilizers = NUTRIENT_CONTENT_IN_FERTILIZERS
1106
-
1107
- # Устанавливаем параметры азота
1108
- calculator.target_profile['N (NO3-)'] = TOTAL_NITROGEN * (NO3_RATIO / (NO3_RATIO + NH4_RATIO))
1109
- calculator.target_profile['N (NH4+)'] = TOTAL_NITROGEN * (NH4_RATIO / (NO3_RATIO + NH4_RATIO))
1110
-
1111
- # Выполняем расчет
1112
- results = calculator.calculate()
1113
-
1114
- # Формируем ответ
 
 
 
 
 
 
1115
  response = {
1116
- 'actual_profile': calculator.actual_profile,
1117
- 'fertilizers': results,
1118
- 'total_ec': calculator.calculate_ec(),
1119
- 'total_ppm': sum(calculator.actual_profile.values()),
1120
- 'nitrogen_ratios': {
1121
- 'NO3_RATIO': NO3_RATIO,
1122
- 'NH4_RATIO': NH4_RATIO,
1123
- 'TOTAL_NITROGEN': TOTAL_NITROGEN
1124
- }
1125
  }
1126
-
1127
- # Округляем все числовые значения
1128
- rounded_response = round_floats(response, rounding_precision)
1129
-
1130
- # Для миллиграммов применяем целочисленное округление
1131
- if 'fertilizers' in rounded_response:
1132
- for fert in rounded_response['fertilizers'].values():
1133
- if 'миллиграммы' in fert:
1134
- fert['миллиграммы'] = int(round(fert['миллиграммы']))
1135
-
1136
- return jsonify(rounded_response)
1137
-
1138
  except Exception as e:
1139
  return jsonify({'error': str(e)}), 500
1140
 
@@ -1151,6 +958,8 @@ def handle_calculation():
1151
 
1152
 
1153
 
 
 
1154
 
1155
 
1156
  if __name__ == '__main__':
 
756
 
757
 
758
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
759
  class NutrientCalculator:
760
  def __init__(self, volume_liters=1.0):
761
  self.volume = volume_liters
762
  self.results = {}
763
+ self.actual_profile = {}
764
+ self.fertilizers = {}
 
765
  self.total_ec = 0.0
766
 
767
+ # Инициализация весов компенсации
768
+ self.compensation_weights = {
769
+ "POTASSIUM_NITRATE": {"weight": 0.5, "fert": "Калий азотнокислый", "main_element": "K"},
770
+ "CALCIUM_NITRATE": {"weight": 0.3, "fert": "Кальциевая селитра", "main_element": "Ca"},
771
+ "POTASSIUM_SULFATE": {"weight": 0.2, "fert": "Калий сернокислый", "main_element": "K"}
 
 
772
  }
773
 
774
  def _label(self, element):
 
775
  labels = {
776
  'N (NO3-)': 'NO3',
777
  'N (NH4+)': 'NH4'
778
  }
779
  return labels.get(element, element)
780
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
781
  def _apply(self, fert_name, main_element, required_ppm):
782
  if required_ppm <= 0:
783
  return
784
+
785
  try:
786
+ content = self.fertilizers[fert_name].get(main_element, 0)
787
+ if content == 0:
788
+ raise KeyError(f"Элемент {main_element} отсутствует в удобрении {fert_name}")
789
+
790
  grams = (required_ppm * self.volume) / (content * 1000)
791
+
792
  if fert_name not in self.results:
793
  result = {
794
  'граммы': 0.0,
 
798
  for element in self.fertilizers[fert_name]:
799
  result[f'внесет {self._label(element)}'] = 0.0
800
  self.results[fert_name] = result
801
+
802
  self.results[fert_name]['граммы'] += grams
803
+ self.results[fert_name]['миллиграммы'] = int(grams * 1000)
804
+
805
  fert_ec = 0.0
806
  for element, percent in self.fertilizers[fert_name].items():
807
  added_ppm = (grams * percent * 1000) / self.volume
808
  self.results[fert_name][f'внесет {self._label(element)}'] += added_ppm
809
+ self.actual_profile[element] = self.actual_profile.get(element, 0) + added_ppm
810
+ fert_ec += added_ppm * 0.0015 # Примерный коэффициент EC
811
+
812
  self.results[fert_name]['вклад в EC'] += fert_ec
813
  self.total_ec += fert_ec
814
  except KeyError as e:
815
+ print(f"Ошибка: {str(e)}")
816
  raise
817
 
818
+ def _compensate_element(self, element, target_profile):
819
+ needed = target_profile[element] - self.actual_profile.get(element, 0)
820
+ if needed <= 0:
 
 
 
821
  return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
822
 
823
+ candidates = []
824
+ for weight_key, weight_data in self.compensation_weights.items():
825
+ fert_name = weight_data["fert"]
826
+ if element in self.fertilizers.get(fert_name, {}):
827
+ candidates.append({
828
+ 'name': fert_name,
829
+ 'weight': weight_data["weight"],
830
+ 'content': self.fertilizers[fert_name][element]
831
+ })
832
+
833
+ if not candidates:
834
+ raise ValueError(f"Нет удобрений для элемента {element}")
835
+
836
+ total_weight = sum(c['weight'] for c in candidates)
837
+ for candidate in candidates:
838
+ share = candidate['weight'] / total_weight
839
+ ppm_to_apply = needed * share
840
+ self._apply(candidate['name'], element, ppm_to_apply)
841
+
842
+ def calculate(self, target_profile):
843
  try:
844
+ # Вносим магний
845
+ self._apply("Сульфат магния", "Mg", target_profile['Mg'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
846
 
847
+ # Вносим кальций через компенсацию
848
+ self._compensate_element("Ca", target_profile)
849
 
850
+ # Вносим фосфор
851
+ self._apply("Монофосфат калия", "P", target_profile['P'])
852
 
853
+ # Вносим аммонийный азот
854
+ self._apply("Аммоний азотнокислый", "N (NH4+)", target_profile['N (NH4+)'])
855
 
856
+ # Компенсируем нитратный азот
857
+ self._compensate_element("N (NO3-)", target_profile)
858
 
859
+ # Компенсируем серу
860
+ self._compensate_element("S", target_profile)
861
 
862
+ # Компенсируем калий
863
+ self._compensate_element("K", target_profile)
864
 
865
+ return self.results
866
+ except Exception as e:
867
+ print(f"Ошибка при расчёте: {str(e)}")
868
+ raise
869
 
870
 
871
+ # Роут для обработки расчетов
 
 
 
 
 
 
 
 
 
 
 
 
872
  @app.route('/calculation', methods=['POST'])
873
  def handle_calculation():
874
  try:
875
  data = request.get_json()
876
+
 
 
 
877
  # Проверка обязательных полей
878
  if not data or 'fertilizerConstants' not in data or 'profileSettings' not in data:
879
  return jsonify({'error': 'Неверный формат данных'}), 400
880
+
881
+ # Инициализация калькулятора
882
+ calculator = NutrientCalculator(volume_liters=float(data['profileSettings'].get('liters', 100)))
883
+
884
+ # Настройка удобрений из запроса
885
+ calculator.fertilizers = {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
886
  "Кальциевая селитра": {
887
+ "N (NO3-)": float(data['fertilizerConstants']["Кальциевая селитра"].get("N (NO3-)", 0.11863)),
888
+ "Ca": float(data['fertilizerConstants']["Кальциевая селитра"].get("Ca", 0.16972))
889
  },
890
  "Калий азотнокислый": {
891
+ "N (NO3-)": float(data['fertilizerConstants']["Калий азотнокислый"].get("N (NO3-)", 0.136)),
892
+ "K": float(data['fertilizerConstants']["Калий азотнокислый"].get("K", 0.382))
893
  },
894
  "Аммоний азотнокислый": {
895
+ "N (NO3-)": float(data['fertilizerConstants']["Аммоний азотнокислый"].get("N (NO3-)", 0.17499)),
896
+ "N (NH4+)": float(data['fertilizerConstants']["Аммоний азотнокислый"].get("N (NH4+)", 0.17499))
897
  },
898
  "Сульфат магния": {
899
+ "Mg": float(data['fertilizerConstants']["Сульфат магния"].get("Mg", 0.09861)),
900
+ "S": float(data['fertilizerConstants']["Сульфат магния"].get("S", 0.13010))
901
  },
902
  "Монофосфат калия": {
903
+ "P": float(data['fertilizerConstants']["Монофосфат калия"].get("P", 0.218)),
904
+ "K": float(data['fertilizerConstants']["Монофосфат калия"].get("K", 0.275))
905
  },
906
  "Калий сернокислый": {
907
+ "K": float(data['fertilizerConstants']["Калий сернокислый"].get("K", 0.44874)),
908
+ "S": float(data['fertilizerConstants']["Калий сернокислый"].get("S", 0.18401))
909
  }
910
  }
911
+
912
+ # Настройка целевого профиля
913
+ total_n = float(data['profileSettings'].get('TOTAL_NITROGEN', 125.0))
914
+ no3_ratio = float(data['profileSettings'].get('NO3_RATIO', 8.25))
915
+ nh4_ratio = 1.0
916
+
917
+ target_profile = {
918
+ 'P': float(data['profileSettings'].get('P', 31.0)),
919
+ 'K': float(data['profileSettings'].get('K', 210.0)),
920
+ 'Mg': float(data['profileSettings'].get('Mg', 24.0)),
921
+ 'Ca': float(data['profileSettings'].get('Ca', 84.0)),
922
+ 'S': float(data['profileSettings'].get('S', 56.439)),
923
+ 'N (NO3-)': total_n * (no3_ratio / (no3_ratio + nh4_ratio)),
924
+ 'N (NH4+)': total_n * (nh4_ratio / (no3_ratio + nh4_ratio))
925
+ }
926
+
927
+ # Выполнение расчета
928
+ results = calculator.calculate(target_profile)
929
+
930
+ # Подготовка ответа
931
  response = {
932
+ "actual_profile": calculator.actual_profile,
933
+ "fertilizers": results,
934
+ "nitrogen_ratios": {
935
+ "NH4_RATIO": nh4_ratio,
936
+ "NO3_RATIO": no3_ratio,
937
+ "TOTAL_NITROGEN": total_n
938
+ },
939
+ "total_ec": round(calculator.total_ec, 2),
940
+ "total_ppm": round(sum(calculator.actual_profile.values()), 3)
941
  }
942
+
943
+ return jsonify(response)
944
+
 
 
 
 
 
 
 
 
 
945
  except Exception as e:
946
  return jsonify({'error': str(e)}), 500
947
 
 
958
 
959
 
960
 
961
+
962
+
963
 
964
 
965
  if __name__ == '__main__':