Розробка мобільного додатку для керування 3D-принтером

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Розробка мобільного додатку для керування 3D-принтером
Середній
~1-2 тижні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Розробка мобільного додатку для управління 3D-принтером

Більшість сучасних 3D-принтерів на мікропрограмному забезпеченні Marlin або Klipper керуються через OctoPrint або Moonraker — REST API + WebSocket на основі G-code. Задача мобільного додатку: завантажити файл G-code, запустити друк, стежити за температурами та прогресом, дивитися на веб-камеру та зупиняти при проблемах. Усе це вже вирішено на рівні API, основна складність полягає в UX та надійній обробці нестабільного WiFi-з'єднання (принтер у майстерні, телефон — де завгодно).

OctoPrint API: основні кінцеві точки

interface OctoPrintApi {
    @GET("api/printer")
    suspend fun getPrinterState(): PrinterState

    @GET("api/job")
    suspend fun getCurrentJob(): JobInfo

    @POST("api/job")
    suspend fun controlJob(@Body command: JobCommand): Response<Unit>

    @GET("api/files/{location}")
    suspend fun getFiles(@Path("location") location: String = "local"): FilesResponse

    @Multipart
    @POST("api/files/{location}")
    suspend fun uploadFile(
        @Path("location") location: String,
        @Part file: MultipartBody.Part,
        @Part("print") print: RequestBody,  // "true" для негайного старту
    ): UploadResponse

    @POST("api/printer/command")
    suspend fun sendGCode(@Body command: GCodeCommand): Response<Unit>
}

data class PrinterState(
    val temperature: TemperatureState,
    val state: StateFlags,
)

data class TemperatureState(
    val tool0: ToolTemp,
    val bed: ToolTemp,
)

data class ToolTemp(
    val actual: Double,
    val target: Double,
    val offset: Double,
)

Реальний час через WebSocket

Температури та прогрес приходять через OctoPrint WebSocket (/sockjs/websocket). События надходять кожні 1-2 секунди:

class OctoPrintSocket(private val baseUrl: String, private val apiKey: String) {
    fun observe(): Flow<OctoPrintEvent> = callbackFlow {
        val client = OkHttpClient()
        val ws = client.newWebSocket(
            Request.Builder().url("ws://$baseUrl/sockjs/websocket")
                .header("X-Api-Key", apiKey).build(),
            object : WebSocketListener() {
                override fun onOpen(webSocket: WebSocket, response: Response) {
                    // Аутентифікація через перше повідомлення
                    webSocket.send("""{"auth": "$apiKey"}""")
                }

                override fun onMessage(webSocket: WebSocket, text: String) {
                    val event = parseEvent(text)
                    trySend(event)
                }
            }
        )
        awaitClose { ws.close(1000, null) }
    }

    private fun parseEvent(json: String): OctoPrintEvent {
        // Типи подій: "current", "history", "event", "plugin"
        val root = JsonParser.parseString(json).asJsonObject
        return when {
            root.has("current") -> OctoPrintEvent.Current(
                parsePrinterState(root["current"].asJsonObject))
            root.has("event") -> OctoPrintEvent.PrintEvent(
                root["event"].asJsonObject["type"].asString)
            else -> OctoPrintEvent.Unknown
        }
    }
}

Камера: MJPEG-потік

OctoPrint транслює MJPEG через /webcam/?action=stream. Coil та Glide не підтримують MJPEG — потрібен спеціальний компонент:

class MjpegStream(private val url: String) {
    fun frames(): Flow<Bitmap> = flow {
        val connection = URL(url).openConnection() as HttpURLConnection
        val inputStream = BufferedInputStream(connection.inputStream)
        val buffer = ByteArrayOutputStream()

        while (true) {
            val byte = inputStream.read()
            if (byte == -1) break

            buffer.write(byte)
            val data = buffer.toByteArray()

            // Маркер кінця JPEG (FF D9)
            if (data.size >= 2 &&
                data[data.size - 2] == 0xFF.toByte() &&
                data[data.size - 1] == 0xD9.toByte()) {
                val bitmap = BitmapFactory.decodeByteArray(data, 0, data.size)
                if (bitmap != null) emit(bitmap)
                buffer.reset()
            }
        }
    }.flowOn(Dispatchers.IO)
}

Moonraker (Klipper) як альтернатива

Принтери на Klipper використовують Moonraker API — більш сучасний REST + WebSocket (/websocket з JSON-RPC). Концепції ті самі, кінцеві точки інші: /printer/objects/query для стану, /printer/gcode/script для команд G-code, Fluidd/Mainsail як веб-інтерфейси.

Завантаження великих файлів G-code (100+ MB) через Moonraker з прогресом:

Future<void> uploadGCode(File file, void Function(double) onProgress) async {
  final stream = http.ByteStream(file.openRead());
  final length = await file.length();
  final request = http.MultipartRequest('POST',
      Uri.parse('$baseUrl/server/files/upload'));
  request.files.add(http.MultipartFile('file', stream, length,
      filename: file.path.split('/').last));

  final response = await request.send();
  // Прогрес відстежується через Content-Length та отримані байти зі потоку
}

Розробка мобільного додатку для управління 3D-принтером (OctoPrint/Moonraker): 4–6 тижнів. Підтримка кількох принтерів, історія температур та сповіщення про завершення: 7–10 тижнів. Вартість розраховується індивідуально.