DmitrMakeev commited on
Commit
9620880
·
verified ·
1 Parent(s): 14165cc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -35
app.py CHANGED
@@ -801,7 +801,7 @@ class NutrientCalculator:
801
  self.actual_profile = {k: 0.0 for k in self.target_profile}
802
  self.total_ec = 0.0
803
  self.fertilizers = {}
804
-
805
  # Коэффициенты для расчета EC (мСм/см на ppm)
806
  self.ec_coefficients = {
807
  'P': 0.0012, 'K': 0.0018, 'Mg': 0.0015,
@@ -809,6 +809,13 @@ class NutrientCalculator:
809
  'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
810
  }
811
 
 
 
 
 
 
 
 
812
  def _apply_fertilizer(self, fert_name: str, element: str, ppm: float):
813
  """Основной метод внесения удобрений с расчетом EC"""
814
  try:
@@ -830,11 +837,11 @@ class NutrientCalculator:
830
  self.results[fert_name]['граммы'] += grams
831
  self.results[fert_name]['миллиграммы'] = int(self.results[fert_name]['граммы'] * 1000)
832
 
833
- # Обновляем все элементы из удобрения и рассчитываем EC
834
  fert_ec = 0.0
835
  for el, percent in self.fertilizers[fert_name].items():
836
  added_ppm = (grams * percent * 1000) / self.volume
837
- self.actual_profile[el] = self.actual_profile.get(el, 0) + added_ppm
838
  self.results[fert_name]['внесенные ppm'][el] = self.results[fert_name]['внесенные ppm'].get(el, 0) + added_ppm
839
  fert_ec += added_ppm * self.ec_coefficients.get(el, 0.0015)
840
 
@@ -842,51 +849,61 @@ class NutrientCalculator:
842
  self.total_ec += fert_ec
843
 
844
  except KeyError as e:
845
- raise ValueError(f"Неверный элемент или удобрение: {str(e)}")
846
 
847
  def calculate_ec(self) -> float:
848
- """Расчет общей электропроводности"""
849
  return round(self.total_ec, 2)
850
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
851
  def calculate(self) -> Dict[str, Any]:
852
- """Основная логика расчёта"""
853
  try:
854
- # 1. Вносим магний и серу
855
  self._apply_fertilizer("Сульфат магния", "Mg", self.target_profile['Mg'])
856
 
857
  # 2. Вносим аммонийный азот
858
- nh4_needed = self.target_profile['N (NH4+)'] - self.actual_profile['N (NH4+)']
859
- if nh4_needed > 0:
860
- self._apply_fertilizer("Аммоний азотнокислый", "N (NH4+)", nh4_needed)
861
 
862
- # 3. Вносим нитратный азот
863
- no3_needed = self.target_profile['N (NO3-)'] - self.actual_profile['N (NO3-)']
864
- if no3_needed > 0:
865
- # Через кальциевую селитру (если нужен кальций)
866
- ca_needed = self.target_profile['Ca'] - self.actual_profile['Ca']
867
- if ca_needed > 0:
868
- self._apply_fertilizer("Кальциевая селитра", "N (NO3-)", min(no3_needed, ca_needed/0.16972*0.11863))
869
-
870
- # Через калийную селитру (остаток)
871
- remaining_no3 = self.target_profile['N (NO3-)'] - self.actual_profile['N (NO3-)']
872
- if remaining_no3 > 0:
873
- self._apply_fertilizer("Калий азотнокислый", "N (NO3-)", remaining_no3)
874
 
875
  # 4. Вносим фосфор
876
  self._apply_fertilizer("Монофосфат калия", "P", self.target_profile['P'])
877
 
878
- # 5. Корректируем калий
879
- k_needed = self.target_profile['K'] - self.actual_profile['K']
880
- if k_needed > 0:
881
- self._apply_fertilizer("Калий сернокислый", "K", k_needed)
882
 
883
  return self._prepare_results()
884
-
885
  except Exception as e:
886
- raise RuntimeError(f"Ошибка расчёта: {str(e)}")
887
 
888
  def _prepare_results(self) -> Dict[str, Any]:
889
- """Форматируем результаты для ответа в Flask"""
890
  return {
891
  'actual_profile': {k: round(v, 2) for k, v in self.actual_profile.items()},
892
  'fertilizers': {
@@ -903,17 +920,13 @@ class NutrientCalculator:
903
  'nitrogen_ratios': {
904
  'NO3': round(self.target_profile['N (NO3-)'], 2),
905
  'NH4': round(self.target_profile['N (NH4+)'], 2)
906
- }
 
907
  }
908
 
909
 
910
 
911
 
912
-
913
-
914
-
915
-
916
-
917
  @app.route('/calculation', methods=['POST'])
918
  def handle_calculation():
919
  try:
 
801
  self.actual_profile = {k: 0.0 for k in self.target_profile}
802
  self.total_ec = 0.0
803
  self.fertilizers = {}
804
+
805
  # Коэффициенты для расчета EC (мСм/см на ppm)
806
  self.ec_coefficients = {
807
  'P': 0.0012, 'K': 0.0018, 'Mg': 0.0015,
 
809
  'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
810
  }
811
 
812
+ # Веса для компенсации (приоритеты)
813
+ self.compensation_weights = {
814
+ 'Калий азотнокислый': {'weight': 0.5, 'main_elements': ['K', 'N (NO3-)']},
815
+ 'Кальциевая селитра': {'weight': 0.3, 'main_elements': ['Ca', 'N (NO3-)']},
816
+ 'Калий сернокислый': {'weight': 0.2, 'main_elements': ['K', 'S']}
817
+ }
818
+
819
  def _apply_fertilizer(self, fert_name: str, element: str, ppm: float):
820
  """Основной метод внесения удобрений с расчетом EC"""
821
  try:
 
837
  self.results[fert_name]['граммы'] += grams
838
  self.results[fert_name]['миллиграммы'] = int(self.results[fert_name]['граммы'] * 1000)
839
 
840
+ # Расчет EC и внесенных ppm
841
  fert_ec = 0.0
842
  for el, percent in self.fertilizers[fert_name].items():
843
  added_ppm = (grams * percent * 1000) / self.volume
844
+ self.actual_profile[el] += added_ppm
845
  self.results[fert_name]['внесенные ppm'][el] = self.results[fert_name]['внесенные ppm'].get(el, 0) + added_ppm
846
  fert_ec += added_ppm * self.ec_coefficients.get(el, 0.0015)
847
 
 
849
  self.total_ec += fert_ec
850
 
851
  except KeyError as e:
852
+ raise ValueError(f"Ошибка в данных удобрений: {str(e)}")
853
 
854
  def calculate_ec(self) -> float:
855
+ """Возвращает общую электропроводность (EC)"""
856
  return round(self.total_ec, 2)
857
 
858
+ def _compensate_element(self, element: str, needed_ppm: float):
859
+ """Компенсация дефицита элемента с учетом весов"""
860
+ suitable_ferts = [
861
+ (fert_name, fert_data)
862
+ for fert_name, fert_data in self.fertilizers.items()
863
+ if element in fert_data
864
+ ]
865
+
866
+ if not suitable_ferts:
867
+ raise ValueError(f"Нет удобрений для элемента {element}")
868
+
869
+ # Сортировка по весам
870
+ suitable_ferts.sort(
871
+ key=lambda x: self.compensation_weights.get(x[0], {}).get('weight', 0.1),
872
+ reverse=True
873
+ )
874
+
875
+ remaining_ppm = needed_ppm
876
+ for fert_name, _ in suitable_ferts:
877
+ if remaining_ppm <= 0:
878
+ break
879
+ self._apply_fertilizer(fert_name, element, remaining_ppm)
880
+ remaining_ppm = self.target_profile[element] - self.actual_profile[element]
881
+
882
  def calculate(self) -> Dict[str, Any]:
883
+ """Основной расчет питательного раствора"""
884
  try:
885
+ # 1. Вносим магний (сульфат магния)
886
  self._apply_fertilizer("Сульфат магния", "Mg", self.target_profile['Mg'])
887
 
888
  # 2. Вносим аммонийный азот
889
+ self._apply_fertilizer("Аммоний азотнокислый", "N (NH4+)", self.target_profile['N (NH4+)'])
 
 
890
 
891
+ # 3. Компенсируем нитратный азот
892
+ self._compensate_element("N (NO3-)", self.target_profile['N (NO3-)'])
 
 
 
 
 
 
 
 
 
 
893
 
894
  # 4. Вносим фосфор
895
  self._apply_fertilizer("Монофосфат калия", "P", self.target_profile['P'])
896
 
897
+ # 5. Компенсируем калий
898
+ self._compensate_element("K", self.target_profile['K'])
 
 
899
 
900
  return self._prepare_results()
901
+
902
  except Exception as e:
903
+ raise RuntimeError(f"Ошибка расчета: {str(e)}")
904
 
905
  def _prepare_results(self) -> Dict[str, Any]:
906
+ """Подготовка результатов для API"""
907
  return {
908
  'actual_profile': {k: round(v, 2) for k, v in self.actual_profile.items()},
909
  'fertilizers': {
 
920
  'nitrogen_ratios': {
921
  'NO3': round(self.target_profile['N (NO3-)'], 2),
922
  'NH4': round(self.target_profile['N (NH4+)'], 2)
923
+ },
924
+ 'compensation_weights': self.compensation_weights
925
  }
926
 
927
 
928
 
929
 
 
 
 
 
 
930
  @app.route('/calculation', methods=['POST'])
931
  def handle_calculation():
932
  try: