Insulin pump simulator in telegram bot format

The insulin pump simulator as a desktop application, which did not arouse interest among the general public, determined the need to look for another format. A telegram bot in Python was chosen as a new format. In doing so, we had to sacrifice some of the functionality, but this simplified the process of starting to work with the simulator. But first things first.

The main goal of the development is a simulator for selecting insulin therapy settings with a feedback response in the form of a glucose value.

For navigation in the bot, a menu has been developed, presented below

Menu

Menu

The first task is to develop a patient generator. Generating this data using a random number generator is a working idea, but it is far from reality. After all, in medicine, the ratios of all the interrelated parameters that characterize a patient have long been formed: age, weight, daily insulin dose, UC (carbohydrate ratio), FSI (insulin sensitivity factor), BP (basal profile/basal rate). Let's use the known ratios and teach the future bot to generate patients with “adequate” parameters. Below is the code for the patient generation module.

 if call.data == "btn_new"  and chet == 0: # Обработка нажатия inline кнопки для вывода списка продуктов

        users[call.from_user.id]['uk_et'] = 0
        users[call.from_user.id]['phi_et'] = 0
        users[call.from_user.id]['bp_et'] = 0
        users[call.from_user.id]['uk'] = 0
        users[call.from_user.id]['phi'] = 0
        users[call.from_user.id]['bp'] = 0
        users[call.from_user.id]['mode'] = 0
        users[call.from_user.id]['chas'] = 0
        users[call.from_user.id]['summ_gluk'] = 5.5
        users[call.from_user.id]['N_gluk'] = 1
        users[call.from_user.id]['gluk_tek'] = 5.5
        users[call.from_user.id]['kol_xe'] = 0
        users[call.from_user.id]['about'] = " "
        users[call.from_user.id]['insulin'] = 0  # Сброс режима

        fin_stroka = []
        fin_stroka.append("Описание пациента:")
        temp_vozr = random.randint(1, 69)
        fin_stroka.append("1.Возраст пациента [лет]: " + str(temp_vozr))
        if temp_vozr == 1:
            temp_ves = 10 + random.randint(0, 2)
        elif temp_vozr == 2:
            temp_ves = 11 + random.randint(0, 3)
        elif temp_vozr == 3:
            temp_ves = 13 + random.randint(0, 2)
        elif temp_vozr == 4:
            temp_ves = 13 + random.randint(0, 5)
        elif temp_vozr == 5:
            temp_ves = 15 + random.randint(0, 7)
        elif temp_vozr == 6:
            temp_ves = 18 + random.randint(0, 4)
        elif temp_vozr == 7:
            temp_ves = 20 + random.randint(0, 8)
        elif temp_vozr == 8:
            temp_ves = 22 + random.randint(0, 9)
        elif temp_vozr == 9:
            temp_ves = 25 + random.randint(0, 10)
        elif temp_vozr == 10:
            temp_ves = 28 + random.randint(0, 10)
        elif temp_vozr == 11:
            temp_ves = 30 + random.randint(0, 11)
        elif temp_vozr == 12:
            temp_ves = 34 + random.randint(0, 7)
        elif temp_vozr == 13:
            temp_ves = 38 + random.randint(0, 15)
        elif temp_vozr == 14:
            temp_ves = 44 + random.randint(0, 13)
        elif temp_vozr == 15:
            temp_ves = 46 + random.randint(0, 23)
        elif temp_vozr == 16:
            temp_ves = 48 + random.randint(0, 27)
        elif temp_vozr == 17:
            temp_ves = 49 + random.randint(0, 30)
        else:
            temp_ves = 51 + random.randint(0, 48)
        fin_stroka.append("2.Вес пациента [кг]: " + str(temp_ves))

        if temp_vozr > 0 and temp_vozr <= 10:
            temp_sdi = round(temp_ves * (7 + random.randint(0, 2)) / 10, 0)
        else:
            temp_sdi = round(temp_ves * (10 + random.randint(0, 9)) / 10, 0)

        temp_staz = random.randint(0, 4)
        if temp_staz < 2:
            temp_sdi = round(temp_ves * (3 + random.randint(0, 2)) / 10, 0)
            #        bot.send_message(message.chat.id, "Стаж сахарного диабета меньше 2 лет.")
            fin_stroka.append("3.Стаж сахарного диабета меньше 2 лет.")

        else:
            fin_stroka.append("3.Стаж сахарного диабета больше 2 лет.")

        fin_stroka.append("4.Суточная доза инсулина [ЕД]: " + str(temp_sdi))
        temp_staz = random.randint(0, 4)
        if temp_staz < 2:
            temp_sdi = round(temp_sdi * 0.8)
            fin_stroka.append("5.Частые гипогликемии.")
        elif temp_staz > 1 and temp_staz < 4:
            temp_sdi = round(temp_sdi * 0.9)
            fin_stroka.append("5.Хорошие показатели глюкозы в крови, редкие гипогликемии.")
        else:
            fin_stroka.append("5.Высокие показатели глюкозы в крови.")

        # Определение БП, УК
        if temp_vozr < 7:
            users[call.from_user.id]['bp_et'] = round(temp_sdi * (30 + random.randint(0, 4)) / (100 * 24), 1)

        elif temp_vozr < 13 and temp_vozr > 6:
            users[call.from_user.id]['bp_et'] = round(temp_sdi * (35 + random.randint(0, 4)) / (100 * 24), 1)
        else:
            users[call.from_user.id]['bp_et'] = round(temp_sdi * (40 + random.randint(0, 9)) / (100 * 24), 1)

        users[call.from_user.id]['uk_et'] = round(temp_sdi * random.randint(12, 20) / (10 * temp_ves), 1)

        users[call.from_user.id]['phi_et'] = round(random.randint(100, 110) / temp_sdi, 1)

        bot.send_message(call.from_user.id, '\n'.join(fin_stroka))
        users[call.from_user.id]['about'] = fin_stroka

After executing this code, the user is presented with a description of the patient. Based on the description, the user can determine the approximate coefficients of the UC, FCI and BP. This description is available at any stage of the task by clicking on the “About the patient” button.

Description option

Description option

The “Info” button, the code for which is presented below, is designed to display current information about the simulator state. This information allows you to track changes in glucose, view current settings and the value of glycated hemoglobin for the simulation period.

Information about the simulator state

Information about the simulator state

    if call.data == "btn_info"  and chet == 0: 
        gg = round((users[call.from_user.id]['summ_gluk']*0.6302/users[call.from_user.id]['N_gluk'])+1.584, 1)
        fin_stroka = []
        fin_stroka.append("Время: " + str(users[call.from_user.id]['chas'])+":00")
        fin_stroka.append("                         ")
        fin_stroka.append("Глюкоза [мМ/л]: " + str(round(users[call.from_user.id]['gluk_tek'],1)))
        fin_stroka.append("Еда [ХЕ]: " + str(users[call.from_user.id]['kol_xe']))
        fin_stroka.append("Инсулин [ЕД]: " + str(users[call.from_user.id]['insulin']))
        fin_stroka.append("                         ")
        fin_stroka.append("Текущие настройки:")
        fin_stroka.append("БП [ЕД/ч]: " + str(users[call.from_user.id]['bp']))
        fin_stroka.append("УК [ЕД/ХЕ]: " + str(users[call.from_user.id]['uk']))
        fin_stroka.append("ФЧИ [мМ/л]: " + str(users[call.from_user.id]['phi']))
        fin_stroka.append("                         ")
        fin_stroka.append("Гликированный гемоглобин: " + str(gg))
        bot.send_message(call.message.chat.id,  '\n'.join(fin_stroka))

The “Food” button allows you to simulate eating. This requires you to specify the amount of XE.

    if users[message.from_user.id]['mode'] == 1:
        if is_number(message.text):
            users[message.from_user.id]['kol_xe'] = float(message.text)
            users[message.from_user.id]['mode'] = 0
            menu(message)  
        else:
            bot.send_message(message.chat.id, "Можно ввести только число")
            bot.send_message(message.chat.id, "Сколько ХЕ?")

The “Insulin” button launches the bolus calculator, which allows you to calculate the amount of insulin for correction and food. A detailed calculation is available to the user. In this case, the calculation is carried out in accordance with the values ​​of the UC, FCI and BP set in the simulator.

Bolus calculator

Bolus calculator

    if call.data == "btn_insulin" and chet == 0:  
        if users[call.from_user.id]['uk'] != 0 and users[call.from_user.id]['bp'] != 0 and users[call.from_user.id]['phi'] != 0:
            fin_stroka = []
            fin_stroka.append("Помощник болюса:")
            eat = users[call.from_user.id]['kol_xe']*users[call.from_user.id]['uk']
            fin_stroka.append("Инсулин на еду [ЕД]: " + str(users[call.from_user.id]['kol_xe'])+" * "+str(users[call.from_user.id]['uk'])+" = "+str(round(eat, 1)))
            korr = (users[call.from_user.id]['gluk_tek']-7)/users[call.from_user.id]['phi']
            fin_stroka.append("Инсулин на коррекц. [ЕД]: (" + str(users[call.from_user.id]['gluk_tek'])+" - 7)/ "+str(users[call.from_user.id]['phi'])+" = "+str(round(korr, 1)))
            itog = eat+korr
            fin_stroka.append("Итого [ЕД]:" + str(round(eat, 1))+" + "+str(round(korr, 1))+" = "+ str(round(itog, 1)))
            bot.send_message(call.message.chat.id, '\n'.join(fin_stroka))

            bot.send_message(call.message.chat.id, "Введите количество инсулина[ЕД]")
            chet = 1  # Выбран режим работы
            bot.register_next_step_handler(call.message, btn_insulin)  # Вызов функции калькулятора болюса
        else : bot.send_message(call.message.chat.id, "Не введены УК, ФЧИ, БП.")

The buttons UK, FCI and BP are intended for entering the corresponding simulator settings.

The simulation step is started by pressing the “Rewind 2 hours” button. The corresponding code is presented below.

    if call.data == "btn_peremotka" and chet == 0: 
        bot.send_message(call.message.chat.id, "Перемотка времени на 2 часа.")
        if users[call.from_user.id]['chas']<24:
            users[call.from_user.id]['chas'] +=2
        else:
            users[call.from_user.id]['chas'] = 0
        users[call.from_user.id]['summ_gluk'] += users[call.from_user.id]['gluk_tek']
        users[call.from_user.id]['N_gluk'] += 1
        users[call.from_user.id]['gluk_tek'] += (users[call.from_user.id]['bp_et']-users[call.from_user.id]['bp'])*2*users[call.from_user.id]['phi_et']
        users[call.from_user.id]['gluk_tek'] += ((users[call.from_user.id]['kol_xe']*users[call.from_user.id]['uk_et'])-users[call.from_user.id]['insulin'])*users[call.from_user.id]['phi_et']
        users[call.from_user.id]['kol_xe'] = 0
        users[call.from_user.id]['insulin'] = 0

After clicking this button, the simulation step will be performed and the new state of the simulator will be available by clicking on the “Info” button.

!!!This bot is intended solely for testing and determining the relevance of the development and cannot be used to determine pump settings or the amount of insulin without a doctor's recommendation!!!

This bot is currently available for testing.

https://t.me/Sugarnorm_pomp_bot

In the comments, please describe your vision of the problem and possibilities of this format for educational software.

As a direction for further research, I would like to add checking the correctness of the selection of parameters with the output of information about this to the user, maintaining statistics on the number and speed of execution of parameter selection options, an emergency option for terminating the simulator in the event of a glucose value of less than 2 mmol/l or more than 20 mmol/l.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *