Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -686,7 +686,6 @@ def nutri_call():
|
|
686 |
|
687 |
|
688 |
|
689 |
-
|
690 |
class NutrientCalculator:
|
691 |
def __init__(self, volume_liters=1.0):
|
692 |
self.volume = volume_liters
|
@@ -703,77 +702,120 @@ class NutrientCalculator:
|
|
703 |
self.total_ec = 0.0
|
704 |
|
705 |
def set_target_profile(self, profile_data):
|
706 |
-
"""Устанавливаем целевые значения"""
|
707 |
-
|
708 |
-
|
709 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
710 |
|
711 |
def set_fertilizers(self, fertilizers_data):
|
712 |
-
"""
|
713 |
-
self.fertilizers =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
714 |
|
715 |
def calculate(self):
|
716 |
-
"""
|
717 |
try:
|
718 |
-
#
|
719 |
-
self.
|
720 |
-
|
721 |
-
|
722 |
-
self.
|
723 |
|
724 |
-
#
|
725 |
-
|
726 |
-
if no3_needed > 0.1:
|
727 |
-
self._apply("Калий азотнокислый", "N (NO3-)", no3_needed)
|
728 |
|
729 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
730 |
k_deficit = self.target_profile['K'] - self.actual_profile['K']
|
731 |
if k_deficit > 0.1:
|
732 |
-
self.
|
|
|
|
|
|
|
|
|
|
|
733 |
|
734 |
return True
|
735 |
except Exception as e:
|
736 |
print(f"Ошибка расчёта: {str(e)}")
|
737 |
return False
|
738 |
|
739 |
-
def
|
740 |
-
"""
|
741 |
-
if
|
|
|
|
|
|
|
742 |
return
|
743 |
|
744 |
-
content = self.fertilizers[
|
745 |
if content <= 0:
|
746 |
return
|
747 |
|
748 |
grams = (required_ppm * self.volume) / (content * 1000)
|
749 |
|
750 |
-
#
|
751 |
-
if
|
752 |
-
self.results[
|
753 |
-
'grams': 0.0,
|
754 |
-
'adds': {}
|
755 |
-
}
|
756 |
|
757 |
-
self.results[
|
758 |
|
759 |
-
#
|
760 |
-
for
|
761 |
added_ppm = (grams * percent * 1000) / self.volume
|
762 |
-
self.actual_profile[
|
763 |
-
self.results[
|
764 |
|
765 |
# Расчёт EC
|
|
|
|
|
|
|
|
|
|
|
766 |
self.total_ec += sum(
|
767 |
-
added_ppm *
|
768 |
-
|
769 |
-
'Ca': 0.0016, 'S': 0.0014,
|
770 |
-
'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
|
771 |
-
}.get(nutrient, 0.0015)
|
772 |
-
for nutrient, added_ppm in self.results[fert_name]['adds'].items()
|
773 |
)
|
774 |
|
775 |
def get_results(self):
|
776 |
-
"""
|
777 |
return {
|
778 |
'fertilizers': [
|
779 |
{
|
@@ -800,17 +842,21 @@ def handle_calculation():
|
|
800 |
try:
|
801 |
data = request.json
|
802 |
|
803 |
-
#
|
804 |
-
|
805 |
-
|
|
|
806 |
|
807 |
-
|
808 |
-
|
|
|
|
|
|
|
|
|
809 |
|
810 |
-
#
|
|
|
811 |
calculator.set_target_profile(data['profileSettings'])
|
812 |
-
|
813 |
-
# Настраиваем удобрения (принимаем как есть, без преобразований)
|
814 |
calculator.set_fertilizers(data['fertilizerConstants'])
|
815 |
|
816 |
# Расчёт
|
@@ -828,9 +874,8 @@ def handle_calculation():
|
|
828 |
except Exception as e:
|
829 |
return jsonify({
|
830 |
'status': 'error',
|
831 |
-
'message': str(e)
|
832 |
-
}),
|
833 |
-
|
834 |
|
835 |
|
836 |
|
|
|
686 |
|
687 |
|
688 |
|
|
|
689 |
class NutrientCalculator:
|
690 |
def __init__(self, volume_liters=1.0):
|
691 |
self.volume = volume_liters
|
|
|
702 |
self.total_ec = 0.0
|
703 |
|
704 |
def set_target_profile(self, profile_data):
|
705 |
+
"""Устанавливаем целевые значения из запроса"""
|
706 |
+
self.target_profile.update({
|
707 |
+
'P': float(profile_data.get('P', 0)),
|
708 |
+
'K': float(profile_data.get('K', 0)),
|
709 |
+
'Mg': float(profile_data.get('Mg', 0)),
|
710 |
+
'Ca': float(profile_data.get('Ca', 0)),
|
711 |
+
'S': float(profile_data.get('S', 0)),
|
712 |
+
'N (NO3-)': float(profile_data.get('N (NO3-)', 0)), # Берём как есть
|
713 |
+
'N (NH4+)': float(profile_data.get('N (NH4+)', 0)) # Без пересчёта
|
714 |
+
})
|
715 |
|
716 |
def set_fertilizers(self, fertilizers_data):
|
717 |
+
"""Устанавливаем состав удобрений из входных данных"""
|
718 |
+
self.fertilizers = {
|
719 |
+
"Кальциевая селитра": {
|
720 |
+
"N (NO3-)": float(fertilizers_data["Кальциевая селитра"]["N (NO3-)"]),
|
721 |
+
"Ca": float(fertilizers_data["Кальциевая селитра"]["Ca"])
|
722 |
+
},
|
723 |
+
"Калий азотнокислый": {
|
724 |
+
"N (NO3-)": float(fertilizers_data["Калий азотнокислый"]["N (NO3-)"]),
|
725 |
+
"K": float(fertilizers_data["Калий азотнокислый"]["K"])
|
726 |
+
},
|
727 |
+
"Аммоний азотнокислый": {
|
728 |
+
"N (NO3-)": float(fertilizers_data["Аммоний азотнокислый"]["N (NO3-)"]),
|
729 |
+
"N (NH4+)": float(fertilizers_data["Аммоний азотнокислый"]["N (NH4+)"])
|
730 |
+
},
|
731 |
+
"Сульфат магния": {
|
732 |
+
"Mg": float(fertilizers_data["Сульфат магния"]["Mg"]),
|
733 |
+
"S": float(fertilizers_data["Сульфат магния"]["S"])
|
734 |
+
},
|
735 |
+
"Монофосфат калия": {
|
736 |
+
"P": float(fertilizers_data["Монофосфат калия"]["P"]),
|
737 |
+
"K": float(fertilizers_data["Монофосфат калия"]["K"])
|
738 |
+
},
|
739 |
+
"Калий сернокислый": {
|
740 |
+
"K": float(fertilizers_data["Калий сернокислый"]["K"]),
|
741 |
+
"S": float(fertilizers_data["Калий сернокислый"]["S"])
|
742 |
+
}
|
743 |
+
}
|
744 |
|
745 |
def calculate(self):
|
746 |
+
"""Оригинальная логика расчёта без изменений"""
|
747 |
try:
|
748 |
+
# 1. Вносим сульфат магния (Mg + S)
|
749 |
+
self._apply_fertilizer("Сульфат магния", "Mg")
|
750 |
+
|
751 |
+
# 2. Вносим кальциевую селитру (Ca + NO3)
|
752 |
+
self._apply_fertilizer("Кальциевая селитра", "Ca")
|
753 |
|
754 |
+
# 3. Вносим монофосфат калия (P + K)
|
755 |
+
self._apply_fertilizer("Монофосфат калия", "P")
|
|
|
|
|
756 |
|
757 |
+
# 4. Вносим аммоний азотнокислый (NH4 + NO3)
|
758 |
+
self._apply_fertilizer("Аммоний азотнокислый", "N (NH4+)")
|
759 |
+
|
760 |
+
# 5. Довносим NO3 через калийную селитру при необходимости
|
761 |
+
no3_deficit = self.target_profile['N (NO3-)'] - self.actual_profile['N (NO3-)']
|
762 |
+
if no3_deficit > 0.1:
|
763 |
+
self._apply_fertilizer("Калий азотнокислый", "N (NO3-)", no3_deficit)
|
764 |
+
|
765 |
+
# 6. Довносим калий при необходимости
|
766 |
k_deficit = self.target_profile['K'] - self.actual_profile['K']
|
767 |
if k_deficit > 0.1:
|
768 |
+
self._apply_fertilizer("Калий азотнокислый", "K", k_deficit)
|
769 |
+
|
770 |
+
# 7. Довносим серу через сульфат калия при необходимости
|
771 |
+
s_deficit = self.target_profile['S'] - self.actual_profile['S']
|
772 |
+
if s_deficit > 0.1:
|
773 |
+
self._apply_fertilizer("Калий сернокислый", "S", s_deficit)
|
774 |
|
775 |
return True
|
776 |
except Exception as e:
|
777 |
print(f"Ошибка расчёта: {str(e)}")
|
778 |
return False
|
779 |
|
780 |
+
def _apply_fertilizer(self, name, main_element, required_ppm=None):
|
781 |
+
"""Метод внесения удобрений без изменений"""
|
782 |
+
if required_ppm is None:
|
783 |
+
required_ppm = self.target_profile[main_element] - self.actual_profile[main_element]
|
784 |
+
|
785 |
+
if required_ppm <= 0 or name not in self.fertilizers:
|
786 |
return
|
787 |
|
788 |
+
content = self.fertilizers[name].get(main_element, 0)
|
789 |
if content <= 0:
|
790 |
return
|
791 |
|
792 |
grams = (required_ppm * self.volume) / (content * 1000)
|
793 |
|
794 |
+
# Запись результатов
|
795 |
+
if name not in self.results:
|
796 |
+
self.results[name] = {'grams': 0.0, 'adds': {}}
|
|
|
|
|
|
|
797 |
|
798 |
+
self.results[name]['grams'] += grams
|
799 |
|
800 |
+
# Обновление профиля
|
801 |
+
for element, percent in self.fertilizers[name].items():
|
802 |
added_ppm = (grams * percent * 1000) / self.volume
|
803 |
+
self.actual_profile[element] += added_ppm
|
804 |
+
self.results[name]['adds'][element] = self.results[name]['adds'].get(element, 0) + added_ppm
|
805 |
|
806 |
# Расчёт EC
|
807 |
+
ec_coefficients = {
|
808 |
+
'P': 0.0012, 'K': 0.0018, 'Mg': 0.0015,
|
809 |
+
'Ca': 0.0016, 'S': 0.0014,
|
810 |
+
'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
|
811 |
+
}
|
812 |
self.total_ec += sum(
|
813 |
+
added_ppm * ec_coefficients.get(element, 0.0015)
|
814 |
+
for element, added_ppm in self.results[name]['adds'].items()
|
|
|
|
|
|
|
|
|
815 |
)
|
816 |
|
817 |
def get_results(self):
|
818 |
+
"""Форматирование результатов без изменений"""
|
819 |
return {
|
820 |
'fertilizers': [
|
821 |
{
|
|
|
842 |
try:
|
843 |
data = request.json
|
844 |
|
845 |
+
# Валидация входных данных
|
846 |
+
required_fields = ['P', 'K', 'Mg', 'Ca', 'S', 'N (NO3-)', 'N (NH4+)', 'liters']
|
847 |
+
if not all(field in data['profileSettings'] for field in required_fields):
|
848 |
+
return jsonify({'status': 'error', 'message': 'Missing required profile fields'}), 400
|
849 |
|
850 |
+
required_fertilizers = [
|
851 |
+
"Кальциевая селитра", "Калий азотнокислый", "Аммоний азотнокислый",
|
852 |
+
"Сульфат магния", "Монофосфат калия", "Калий сернокислый"
|
853 |
+
]
|
854 |
+
if not all(fert in data['fertilizerConstants'] for fert in required_fertilizers):
|
855 |
+
return jsonify({'status': 'error', 'message': 'Missing required fertilizers'}), 400
|
856 |
|
857 |
+
# Иниц��ализация калькулятора
|
858 |
+
calculator = NutrientCalculator(volume_liters=data['profileSettings']['liters'])
|
859 |
calculator.set_target_profile(data['profileSettings'])
|
|
|
|
|
860 |
calculator.set_fertilizers(data['fertilizerConstants'])
|
861 |
|
862 |
# Расчёт
|
|
|
874 |
except Exception as e:
|
875 |
return jsonify({
|
876 |
'status': 'error',
|
877 |
+
'message': f"Server error: {str(e)}"
|
878 |
+
}), 500
|
|
|
879 |
|
880 |
|
881 |
|