Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -691,16 +691,18 @@ NO3_RATIO = 8.00 # Доля нитратного азота
|
|
691 |
NH4_RATIO = 1.00 # Доля аммонийного азота
|
692 |
VOLUME_LITERS = 10 # Объём раствора
|
693 |
|
694 |
-
# Базовый профиль (
|
695 |
BASE_PROFILE = {
|
696 |
'P': 31.000,
|
697 |
'K': 210.694,
|
698 |
'Mg': 24.000,
|
699 |
'Ca': 84.000,
|
700 |
-
'S': 137.397
|
|
|
|
|
701 |
}
|
702 |
|
703 |
-
# Полная база всех возможных удобрений
|
704 |
ALL_FERTILIZERS = {
|
705 |
"Кальциевая селитра": {
|
706 |
"N (NO3-)": 0.118, "Ca": 0.169
|
@@ -712,7 +714,7 @@ ALL_FERTILIZERS = {
|
|
712 |
"K": 0.448, "S": 0.184
|
713 |
},
|
714 |
"Сульфат калия": {
|
715 |
-
"K": 0.448, "S": 0.184
|
716 |
},
|
717 |
"Аммоний азотнокислый": {
|
718 |
"N (NO3-)": 0.175, "N (NH4+)": 0.175
|
@@ -721,24 +723,19 @@ ALL_FERTILIZERS = {
|
|
721 |
"Mg": 0.098, "S": 0.13
|
722 |
},
|
723 |
"Калий фосфорнокислый": {
|
724 |
-
"P": 0.228, "K": 0.287
|
725 |
}
|
726 |
}
|
727 |
|
728 |
class NutrientCalculator:
|
729 |
def __init__(self, volume_liters=1.0, use_k2so4=True, use_kno3=True):
|
730 |
-
"""
|
731 |
-
:param volume_liters: Объём раствора
|
732 |
-
:param use_k2so4: Использовать калий сернокислый (True/False)
|
733 |
-
:param use_kno3: Использовать калий азотнокислый (True/False)
|
734 |
-
"""
|
735 |
self.volume = volume_liters
|
736 |
self.results = {}
|
737 |
-
self.final_profile =
|
738 |
-
self.total_ppm =
|
739 |
self.initial_n_profile = {}
|
740 |
|
741 |
-
# Формируем активные удобрения
|
742 |
self.fertilizers_db = {
|
743 |
"Кальциевая селитра": ALL_FERTILIZERS["Кальциевая селитра"],
|
744 |
"Аммоний азотнокислый": ALL_FERTILIZERS["Аммоний азотнокислый"],
|
@@ -752,26 +749,30 @@ class NutrientCalculator:
|
|
752 |
self.fertilizers_db["Калий азотнокислый"] = ALL_FERTILIZERS["Калий азотнокислый"]
|
753 |
|
754 |
def calculate(self, total_n, no3_ratio, nh4_ratio):
|
|
|
755 |
total_parts = no3_ratio + nh4_ratio
|
756 |
no3 = total_n * (no3_ratio / total_parts)
|
757 |
nh4 = total_n * (nh4_ratio / total_parts)
|
758 |
-
|
759 |
self.initial_n_profile = {
|
760 |
'N (NO3-)': round(no3, 1),
|
761 |
'N (NH4+)': round(nh4, 1)
|
762 |
}
|
763 |
-
|
764 |
-
|
765 |
self.final_profile['N (NO3-)'] = no3
|
766 |
self.final_profile['N (NH4+)'] = nh4
|
767 |
-
self.total_ppm = total_n + sum(BASE_PROFILE.values())
|
768 |
|
769 |
-
#
|
770 |
self._apply_magnesium_sulfate()
|
771 |
self._apply_calcium_nitrate()
|
772 |
self._apply_potassium_phosphate()
|
773 |
-
self._apply_potassium_fertilizers()
|
774 |
self._apply_ammonium_nitrate()
|
|
|
|
|
|
|
|
|
|
|
775 |
return self.results
|
776 |
|
777 |
def _apply_fertilizer(self, fert_name, grams, additions):
|
@@ -781,8 +782,17 @@ class NutrientCalculator:
|
|
781 |
}
|
782 |
self.results[fert_name].update(additions)
|
783 |
|
|
|
|
|
|
|
|
|
|
|
|
|
784 |
def _apply_magnesium_sulfate(self):
|
785 |
mg_need = self.final_profile['Mg']
|
|
|
|
|
|
|
786 |
mg_content = self.fertilizers_db["Сульфат магния"]["Mg"]
|
787 |
grams = (mg_need * self.volume) / (mg_content * 1000)
|
788 |
added_s = grams * self.fertilizers_db["Сульфат магния"]["S"] * 1000 / self.volume
|
@@ -793,6 +803,9 @@ class NutrientCalculator:
|
|
793 |
|
794 |
def _apply_calcium_nitrate(self):
|
795 |
ca_need = self.final_profile['Ca']
|
|
|
|
|
|
|
796 |
ca_content = self.fertilizers_db["Кальциевая селитра"]["Ca"]
|
797 |
grams = (ca_need * self.volume) / (ca_content * 1000)
|
798 |
added_n = grams * self.fertilizers_db["Кальциевая селитра"]["N (NO3-)"] * 1000 / self.volume
|
@@ -803,6 +816,9 @@ class NutrientCalculator:
|
|
803 |
|
804 |
def _apply_potassium_phosphate(self):
|
805 |
p_need = self.final_profile['P']
|
|
|
|
|
|
|
806 |
p_content = self.fertilizers_db["Калий фосфорнокислый"]["P"]
|
807 |
grams = (p_need * self.volume) / (p_content * 1000)
|
808 |
added_k = grams * self.fertilizers_db["Калий фосфорнокислый"]["K"] * 1000 / self.volume
|
@@ -816,30 +832,22 @@ class NutrientCalculator:
|
|
816 |
if k_need <= 0:
|
817 |
return
|
818 |
|
819 |
-
#
|
820 |
if "Калий сернокислый" in self.fertilizers_db:
|
821 |
-
s_deficit =
|
822 |
-
|
823 |
-
|
824 |
-
k2so4_grams = (s_deficit * self.volume) / (s_content * 1000)
|
825 |
-
added_k = k2so4_grams * self.fertilizers_db["Калий сернокислый"]["K"] * 1000 / self.volume
|
826 |
-
|
827 |
-
if added_k > k_need:
|
828 |
-
k2so4_grams = (k_need * self.volume) / (self.fertilizers_db["Калий сернокислый"]["K"] * 1000)
|
829 |
-
added_k = k_need
|
830 |
-
added_s = k2so4_grams * self.fertilizers_db["Калий сернокислый"]["S"] * 1000 / self.volume
|
831 |
-
else:
|
832 |
-
added_s = s_deficit
|
833 |
|
|
|
834 |
self._apply_fertilizer("Калий сернокислый", k2so4_grams, {
|
835 |
-
'внесет K': round(
|
836 |
'внесет S': round(added_s, 2)
|
837 |
})
|
838 |
-
self.final_profile['K']
|
839 |
self.final_profile['S'] -= added_s
|
840 |
-
|
841 |
|
842 |
-
#
|
843 |
if k_need > 0 and "Калий азотнокислый" in self.fertilizers_db:
|
844 |
kno3_grams = (k_need * self.volume) / (self.fertilizers_db["Калий азотнокислый"]["K"] * 1000)
|
845 |
added_n = kno3_grams * self.fertilizers_db["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
@@ -852,14 +860,11 @@ class NutrientCalculator:
|
|
852 |
self.final_profile['K'] = 0
|
853 |
self.final_profile['N (NO3-)'] -= added_n
|
854 |
|
855 |
-
# Если остался дефицит и нет подходящих удобрений
|
856 |
-
if k_need > 0:
|
857 |
-
print(f" Внимание: Не удалось полностью покрыть дефицит K ({k_need:.2f} ppm)")
|
858 |
-
|
859 |
def _apply_ammonium_nitrate(self):
|
860 |
nh4_need = self.final_profile['N (NH4+)']
|
861 |
if nh4_need <= 0:
|
862 |
return
|
|
|
863 |
nh4_content = self.fertilizers_db["Аммоний азотнокислый"]["N (NH4+)"]
|
864 |
grams = (nh4_need * self.volume) / (nh4_content * 1000)
|
865 |
added_n = grams * self.fertilizers_db["Аммоний азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
@@ -885,7 +890,7 @@ class NutrientCalculator:
|
|
885 |
print("\n" + "="*60)
|
886 |
print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
|
887 |
print("="*60)
|
888 |
-
print(f"Общая концентрация: {self.total_ppm} ppm")
|
889 |
print(f"EC: {self.calculate_ec()} mS/cm")
|
890 |
|
891 |
print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
|
@@ -910,7 +915,7 @@ class NutrientCalculator:
|
|
910 |
|
911 |
# Пример использования
|
912 |
if __name__ == "__main__":
|
913 |
-
# Вариант
|
914 |
calc_with_kno3 = NutrientCalculator(volume_liters=10, use_k2so4=False, use_kno3=True)
|
915 |
calc_with_kno3.calculate(TOTAL_NITROGEN, NO3_RATIO, NH4_RATIO)
|
916 |
calc_with_kno3.print_report()
|
@@ -918,6 +923,5 @@ if __name__ == "__main__":
|
|
918 |
|
919 |
|
920 |
|
921 |
-
|
922 |
if __name__ == '__main__':
|
923 |
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))
|
|
|
691 |
NH4_RATIO = 1.00 # Доля аммонийного азота
|
692 |
VOLUME_LITERS = 10 # Объём раствора
|
693 |
|
694 |
+
# Базовый профиль (7 элементов)
|
695 |
BASE_PROFILE = {
|
696 |
'P': 31.000,
|
697 |
'K': 210.694,
|
698 |
'Mg': 24.000,
|
699 |
'Ca': 84.000,
|
700 |
+
'S': 137.397,
|
701 |
+
'N (NO3-)': 0,
|
702 |
+
'N (NH4+)': 0
|
703 |
}
|
704 |
|
705 |
+
# Полная база всех возможных удобрений (7 удобрений)
|
706 |
ALL_FERTILIZERS = {
|
707 |
"Кальциевая селитра": {
|
708 |
"N (NO3-)": 0.118, "Ca": 0.169
|
|
|
714 |
"K": 0.448, "S": 0.184
|
715 |
},
|
716 |
"Сульфат калия": {
|
717 |
+
"K": 0.448, "S": 0.184
|
718 |
},
|
719 |
"Аммоний азотнокислый": {
|
720 |
"N (NO3-)": 0.175, "N (NH4+)": 0.175
|
|
|
723 |
"Mg": 0.098, "S": 0.13
|
724 |
},
|
725 |
"Калий фосфорнокислый": {
|
726 |
+
"P": 0.228, "K": 0.287
|
727 |
}
|
728 |
}
|
729 |
|
730 |
class NutrientCalculator:
|
731 |
def __init__(self, volume_liters=1.0, use_k2so4=True, use_kno3=True):
|
|
|
|
|
|
|
|
|
|
|
732 |
self.volume = volume_liters
|
733 |
self.results = {}
|
734 |
+
self.final_profile = BASE_PROFILE.copy()
|
735 |
+
self.total_ppm = sum(BASE_PROFILE.values()) + TOTAL_NITROGEN
|
736 |
self.initial_n_profile = {}
|
737 |
|
738 |
+
# Формируем активные удобрения
|
739 |
self.fertilizers_db = {
|
740 |
"Кальциевая селитра": ALL_FERTILIZERS["Кальциевая селитра"],
|
741 |
"Аммоний азотнокислый": ALL_FERTILIZERS["Аммоний азотнокислый"],
|
|
|
749 |
self.fertilizers_db["Калий азотнокислый"] = ALL_FERTILIZERS["Калий азотнокислый"]
|
750 |
|
751 |
def calculate(self, total_n, no3_ratio, nh4_ratio):
|
752 |
+
# Рассчитываем баланс азота
|
753 |
total_parts = no3_ratio + nh4_ratio
|
754 |
no3 = total_n * (no3_ratio / total_parts)
|
755 |
nh4 = total_n * (nh4_ratio / total_parts)
|
756 |
+
|
757 |
self.initial_n_profile = {
|
758 |
'N (NO3-)': round(no3, 1),
|
759 |
'N (NH4+)': round(nh4, 1)
|
760 |
}
|
761 |
+
|
762 |
+
# Добавляем азот в профиль
|
763 |
self.final_profile['N (NO3-)'] = no3
|
764 |
self.final_profile['N (NH4+)'] = nh4
|
|
|
765 |
|
766 |
+
# Последовательность внесения удобрений
|
767 |
self._apply_magnesium_sulfate()
|
768 |
self._apply_calcium_nitrate()
|
769 |
self._apply_potassium_phosphate()
|
|
|
770 |
self._apply_ammonium_nitrate()
|
771 |
+
self._apply_potassium_fertilizers()
|
772 |
+
|
773 |
+
# Корректируем отрицательные значения
|
774 |
+
self._adjust_negative_values()
|
775 |
+
|
776 |
return self.results
|
777 |
|
778 |
def _apply_fertilizer(self, fert_name, grams, additions):
|
|
|
782 |
}
|
783 |
self.results[fert_name].update(additions)
|
784 |
|
785 |
+
def _adjust_negative_values(self):
|
786 |
+
# Корректируем отрицательные значения до 0
|
787 |
+
for element in self.final_profile:
|
788 |
+
if self.final_profile[element] < 0:
|
789 |
+
self.final_profile[element] = 0
|
790 |
+
|
791 |
def _apply_magnesium_sulfate(self):
|
792 |
mg_need = self.final_profile['Mg']
|
793 |
+
if mg_need <= 0:
|
794 |
+
return
|
795 |
+
|
796 |
mg_content = self.fertilizers_db["Сульфат магния"]["Mg"]
|
797 |
grams = (mg_need * self.volume) / (mg_content * 1000)
|
798 |
added_s = grams * self.fertilizers_db["Сульфат магния"]["S"] * 1000 / self.volume
|
|
|
803 |
|
804 |
def _apply_calcium_nitrate(self):
|
805 |
ca_need = self.final_profile['Ca']
|
806 |
+
if ca_need <= 0:
|
807 |
+
return
|
808 |
+
|
809 |
ca_content = self.fertilizers_db["Кальциевая селитра"]["Ca"]
|
810 |
grams = (ca_need * self.volume) / (ca_content * 1000)
|
811 |
added_n = grams * self.fertilizers_db["Кальциевая селитра"]["N (NO3-)"] * 1000 / self.volume
|
|
|
816 |
|
817 |
def _apply_potassium_phosphate(self):
|
818 |
p_need = self.final_profile['P']
|
819 |
+
if p_need <= 0:
|
820 |
+
return
|
821 |
+
|
822 |
p_content = self.fertilizers_db["Калий фосфорнокислый"]["P"]
|
823 |
grams = (p_need * self.volume) / (p_content * 1000)
|
824 |
added_k = grams * self.fertilizers_db["Калий фосфорнокислый"]["K"] * 1000 / self.volume
|
|
|
832 |
if k_need <= 0:
|
833 |
return
|
834 |
|
835 |
+
# Сначала используем калий сернокислый (если доступен)
|
836 |
if "Калий сернокислый" in self.fertilizers_db:
|
837 |
+
s_deficit = self.final_profile['S']
|
838 |
+
k2so4_grams = (k_need * self.volume) / (self.fertilizers_db["Калий сернокислый"]["K"] * 1000)
|
839 |
+
added_s = k2so4_grams * self.fertilizers_db["Калий сернокислый"]["S"] * 1000 / self.volume
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
840 |
|
841 |
+
if s_deficit > 0 and added_s <= s_deficit:
|
842 |
self._apply_fertilizer("Калий сернокислый", k2so4_grams, {
|
843 |
+
'внесет K': round(k_need, 2),
|
844 |
'внесет S': round(added_s, 2)
|
845 |
})
|
846 |
+
self.final_profile['K'] = 0
|
847 |
self.final_profile['S'] -= added_s
|
848 |
+
return
|
849 |
|
850 |
+
# Если остался калий, используем калий азотнокислый
|
851 |
if k_need > 0 and "Калий азотнокислый" in self.fertilizers_db:
|
852 |
kno3_grams = (k_need * self.volume) / (self.fertilizers_db["Калий азотнокислый"]["K"] * 1000)
|
853 |
added_n = kno3_grams * self.fertilizers_db["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
|
|
860 |
self.final_profile['K'] = 0
|
861 |
self.final_profile['N (NO3-)'] -= added_n
|
862 |
|
|
|
|
|
|
|
|
|
863 |
def _apply_ammonium_nitrate(self):
|
864 |
nh4_need = self.final_profile['N (NH4+)']
|
865 |
if nh4_need <= 0:
|
866 |
return
|
867 |
+
|
868 |
nh4_content = self.fertilizers_db["Аммоний азотнокислый"]["N (NH4+)"]
|
869 |
grams = (nh4_need * self.volume) / (nh4_content * 1000)
|
870 |
added_n = grams * self.fertilizers_db["Аммоний азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
|
|
890 |
print("\n" + "="*60)
|
891 |
print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
|
892 |
print("="*60)
|
893 |
+
print(f"Общая концентрация: {round(self.total_ppm, 1)} ppm")
|
894 |
print(f"EC: {self.calculate_ec()} mS/cm")
|
895 |
|
896 |
print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
|
|
|
915 |
|
916 |
# Пример использования
|
917 |
if __name__ == "__main__":
|
918 |
+
# Вариант с калием азотнокислым
|
919 |
calc_with_kno3 = NutrientCalculator(volume_liters=10, use_k2so4=False, use_kno3=True)
|
920 |
calc_with_kno3.calculate(TOTAL_NITROGEN, NO3_RATIO, NH4_RATIO)
|
921 |
calc_with_kno3.print_report()
|
|
|
923 |
|
924 |
|
925 |
|
|
|
926 |
if __name__ == '__main__':
|
927 |
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))
|