Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request for Help: Implementing or Using This Project in an Android Kotlin App #71

Closed
MaretArt opened this issue Feb 15, 2025 · 18 comments
Closed
Labels
enhancement New feature or request

Comments

@MaretArt
Copy link

Hi everyone,

I'm currently working on an Android application using Kotlin and I need some assistance with implementing or using this project in my app. It is important to note that I have very limited knowledge of TypeScript and almost no experience with it.

Could anyone with experience in both TypeScript and Kotlin help guide me through this process? Any advice, examples, or resources would be greatly appreciated.

Thank you in advance for your support!

@MaretArt MaretArt added the enhancement New feature or request label Feb 15, 2025
@MultiMote
Copy link
Owner

MultiMote commented Feb 15, 2025

It depends on your needs. If you you only need to embed this app to your app, you can use webview (Capacitor for example). Otherwise you need to port niimbluelib to desired language.

Maybe this project code can help you somehow (first option): https://github.com/dotnetdreamer/capacitor-niimbot-printer

@MaretArt
Copy link
Author

Tergantung pada kebutuhan Anda. Jika Anda hanya perlu menyematkan aplikasi ini ke aplikasi Anda, Anda dapat menggunakan Capacitor. Jika tidak, Anda perlu memindahkan niimbluelib ke bahasa yang diinginkan.

Mungkin kode proyek ini dapat membantu Anda: https://github.com/dotnetdreamer/capacitor-niimbot-printer

I really appreciate your reply and feedback, but what I need is the second option. Do you have any suggestions or anything to port nimbluelib to kotlin?

@MaretArt
Copy link
Author

I have tried several times, but it only works for Niimbot B21. I want it to work, for Niimbot B21 and B1. Can you help me a little?
If you are willing, I will attach a snippet of my code.
thanks a lot

@MultiMote
Copy link
Owner

I really appreciate your reply and feedback, but what I need is the second option. Do you have any suggestions or anything to port nimbluelib to kotlin?

There is a port of niimprint to Kotlin, I think you can extend it or use it as a starting point https://github.com/terratempest/android_niimprint

@MultiMote
Copy link
Owner

I have tried several times, but it only works for Niimbot B21. I want it to work, for Niimbot B21 and B1. Can you help me a little? If you are willing, I will attach a snippet of my code. thanks a lot

Sure

@MultiMote
Copy link
Owner

MultiMote commented Feb 15, 2025

B1 and B21 has differences in print sequence.

See this page: https://multimote.github.io/niimbluelib/documents/NIIMBOT_print_tasks.html

@MaretArt
Copy link
Author

MaretArt commented Feb 15, 2025

Saya sudah mencobanya beberapa kali, tetapi hanya berfungsi untuk Niimbot B21. Saya ingin ini berfungsi untuk Niimbot B21 dan B1. Bisakah Anda membantu saya sedikit? Jika Anda bersedia, saya akan melampirkan cuplikan kode saya. Terima kasih banyak

Tentu

thank you, this is what i have tried

private suspend fun sendCommand(requestCode: Byte, data: ByteArray): ByteArray =
    withContext(Dispatchers.IO) {
        val packet = createPacket(requestCode, data)
        bluetoothSocket!!.outputStream.write(packet)
        bluetoothSocket!!.outputStream.flush()

        Thread.sleep(100)

        val buffer = ByteArray(1024)
        val bytes = bluetoothSocket!!.inputStream.read(buffer)

        return@withContext buffer.copyOfRange(0, bytes)
    }

private fun createPacket(cmd: Byte, data: ByteArray): ByteArray {
    val packetData = ByteBuffer.allocate(data.size + 7)
        .put(0x55.toByte())
        .put(0x55.toByte())
        .put(cmd)
        .put(data.size.toByte())
        .put(data)

    var checksum = cmd.toInt() xor data.size
    data.forEach { checksum = checksum xor it.toInt() }

    packetData.put(checksum.toByte())
    packetData.put(0xAA.toByte())
    packetData.put(0xAA.toByte())

    return packetData.array()
}

suspend fun print(
    bitmap: Bitmap,
    density: Int = 5,
    labelType: Int = 1,
    quantity: Int = 1,
    rotate: Boolean = false,
    invert: Boolean = false
): Boolean {
    if (bluetoothSocket != null) {
        if (bluetoothSocket!!.isConnected) {
            var img = bitmap
            var width = bitmap.width
            var height = bitmap.height

            if (rotate) {
                img = rotate(img)
                width = bitmap.width
                height = bitmap.height
            }

            if (invert)
                img = img.invert()

            setLabelDensity(density)
            setLabelType(labelType)
            allowPrintClear()
            startPrint()
            startPagePrint()
            setDimension(width, height, quantity)

            withContext(Dispatchers.IO) {
                for (packet in encoder(img)) {
                    bluetoothSocket!!.outputStream.write(packet)
                    bluetoothSocket!!.outputStream.flush()
                    delay(10)
                }
            }

            while (!endPagePrint())
                delay(50)

            while (true) {
                val status = getPrintStatus()
                if (status["page"] == quantity)
                    break

                delay(100)
            }

            endPrint()

            return true
        } else
            return false
    } else
        return false
}

private fun encoder(bitmap: Bitmap): List<ByteArray> {
    val packets = mutableListOf<ByteArray>()
    for (y in 0 until bitmap.height) {
        val line = ByteArray(ceil(bitmap.width / 8.0).toInt())
        for (x in 0 until bitmap.width) {
            val pixel = bitmap.getPixel(x, y)
            if (pixel == 0xFF000000.toInt())
                line[x / 8] = line[x / 8] or (1 shl (7 - x % 8)).toByte()
        }

        val header = ByteBuffer.allocate(6)
            .putShort(y.toShort())
            .put(0.toByte())
            .put(0.toByte())
            .put(0.toByte())
            .put(1.toByte())
            .array()

        val packetData = header + line
        packets.add(createPacket(0x83.toByte(), packetData))
    }

    return packets
}

private suspend fun setLabelDensity(n: Int): Boolean {
    require(n in 1..5) { "Density must be between 1 and 5" }
    val resp = sendCommand(0x21.toByte(), byteArrayOf(n.toByte()))
    return resp[4] != 0.toByte()    // i: 2 or 5, res: 0x31 or 49
}

private suspend fun setLabelType(n: Int): Boolean {
    require(n in 1..3) { "Label type must be between 1 and 3" }
    return resp[4] != 0.toByte()    // i: 2 or 5, res: 0x33 or 51
}

private suspend fun allowPrintClear(): Boolean {
    val resp = sendCommand(0x20.toByte(), byteArrayOf(0x01.toByte()))
    return resp[4] != 0.toByte()    // i: 2 or 5, res: 0x30 or 48
}

private suspend fun startPrint(): Boolean {
    val resp = sendCommand(0x01.toByte(), byteArrayOf(0x01.toByte()))
    return resp[4] != 0.toByte()    // i: 2 or 5, res: 0x02 or 2
}

private suspend fun startPagePrint(): Boolean {
    val resp = sendCommand(0x03.toByte(), byteArrayOf(0x01.toByte()))
    return resp[4] != 0.toByte()    // i: 2 or 5, res: 0x04 or 4
}

private suspend fun endPrint(): Boolean {
    val resp = sendCommand(0xF3.toByte(), byteArrayOf(0x01.toByte()))
    return resp[4] != 0.toByte()    // i: 2 or 5, res 0xF4 or 244
}

private suspend fun endPagePrint(): Boolean {
    val resp = sendCommand(0xE3.toByte(), byteArrayOf(0x01.toByte()))
    return resp[4] != 0.toByte()    // i: 2 or 5, res 0xE4 or 228
}

private suspend fun setDimension(width: Int, height: Int): Boolean {
    val data = ByteBuffer.allocate(4)
        .putShort(width.toShort())
        .putShort(height.toShort())
        .array()

    val resp = sendCommand(0x13.toByte(), data)
    return resp[4] != 0.toByte()    // i: 2 or 5, res: 0x14 or 20
}

private suspend fun setDimension(width: Int, height: Int, qty: Int): Boolean {
    val data = ByteBuffer.allocate(6)
        .putShort(width.toShort())
        .putShort(height.toShort())
        .putShort(qty.toShort())
        .array()

    val resp = sendCommand(0x13.toByte(), data)
    return resp[4] != 0.toByte()    // i: 2 or 5, res: 0x14 or 20
}

private suspend fun setQuantity(n: Int): Boolean {
    val data = ByteBuffer.allocate(2)
        .putShort(n.toShort())
        .array()

    val resp = sendCommand(0x15.toByte(), data)
    return resp[4] != 0.toByte()    // i: 2 or 5, res: 0x16 or 22
}

private suspend fun getPrintStatus(): Map<String, Int> {
    val resp = sendCommand(0xA3.toByte(), byteArrayOf(0x01.toByte()))
    val data = resp.copyOfRange(4, resp.size - 1)
    val page = (data[0].toInt() and 0xFF)
    val prog1 = (data[1].toInt() and 0xFF)
    val prog2 = (data[2].toInt() and 0xFF)

    return mapOf(
        "page" to page,
        "progress1" to prog1,
        "progress2" to prog2
    )
}

I would really appreciate and be grateful for any help or input you may have.

@MaretArt
Copy link
Author

B1 and B21 has differences in print sequence.

See this page: https://multimote.github.io/niimbluelib/documents/NIIMBOT_print_tasks.html

thanks,
i have tried to fix it, but when i try to print, it doesn't print anything.
after i try to see the printer response, i see something that i think or maybe it's a mistake when i set the page size, here is the response:

[85, 85, 20, 2, 1, 0, 23, -86, -86]

is that normal? shouldn't the response be the same on index 2 and 5, that is 20 or 0x14?

@MultiMote
Copy link
Owner

MultiMote commented Feb 16, 2025

is that normal?

Yes. Check the real B1 exchange: AndBondStyle/niimprint#31 (comment)
List of request and response codes: https://multimote.github.io/niimbluelib/documents/NIIMBOT_printers_protocol.html#md:list-of-packets

allowPrintClear()

Not needed for B1.

while (!endPagePrint())
delay(50)

For B1 you need to send only single PageEnd.

private suspend fun startPrint(): Boolean {
    val resp = sendCommand(0x01.toByte(), byteArrayOf(0x01.toByte()))
    return resp[4] != 0.toByte()    // i: 2 or 5, res: 0x02 or 2
}

That's not correct for B1. You should use this format (7 data bytes): https://github.com/MultiMote/niimbluelib/blob/19c3072d135eb53b1ff198ab8771a164583bf8bf/src/packets/packet_generator.ts#L168-L170

See the full print task implementation here: https://github.com/MultiMote/niimbluelib/blob/19c3072d135eb53b1ff198ab8771a164583bf8bf/src/print_tasks/B1PrintTask.ts

@MaretArt
Copy link
Author

MaretArt commented Feb 16, 2025

@MultiMote I am very grateful for your input and direction. Overall I have successfully printed using both types of printers (B21 and B1) but when I print on the B1 printer the results shift to the right.
This is the code I use to encode the image:

fun encode(image: Bitmap, printDirection: PrintDirection) : EncodedImage {
    val rowsData = ArrayList<ImageRow>()
    var width = image.width
    var height = image.height
    if (printDirection == PrintDirection.LEFT) {
        width = image.height
        height = image.width
    }

    if (width % 8 != 0)
        throw IllegalArgumentException("Column count must be multiple of 8")

    for (y in 0 until height) {
        var isVoid = true
        var blackPixelCount = 0
        val rowData = ByteArray(width / 8)
        for (x in 0 until (width / 8)) {
            var pixel = 0
            for (bit in 0 until 8) {
                var current = image.getPixel(x * 8 + bit, y)
                if (printDirection == PrintDirection.LEFT)
                    current = image.getPixel(y, x * 8 + bit)

                val r = Color.red(current)
                val g = Color.green(current)
                val b = Color.blue(current)
                if (r != 255 && g != 255 && b != 255) {
                    pixel = pixel or (1 shl (7 - bit))
                    isVoid = false
                    blackPixelCount++
                }
            }

            rowData[x] = pixel.toByte()
        }

        val newPart = ImageRow(
            type = if (isVoid) "void" else "pixels",
            rowNumber = y,
            repeat = 1,
            blackPixelsCount = blackPixelCount,
            rowData = if (isVoid) null else rowData
        )

        if (rowsData.isEmpty())
            rowsData.add(newPart)
        else {
            val lastPacket = rowsData.last()
            var same = newPart.type == lastPacket.type
            if (same && newPart.type == "pixels")
                same = newPart.rowData!!.contentEquals(lastPacket.rowData)

            if (same)
                lastPacket.repeat++
            else
                rowsData.add(newPart)

            if (y % 200 == 199) {
                rowsData.add(
                    ImageRow(
                        type = "check",
                        rowNumber = y,
                        repeat = 0,
                        blackPixelsCount = 0,
                        rowData = null
                    )
                )
            }
        }
    }

    return EncodedImage(width, height, rowsData)
}

and this is the print result:

Image

@MultiMote
Copy link
Owner

MultiMote commented Feb 16, 2025

Please attach the original image and your full packet exchange log (encoded to hex).

Use following format if you can:

>> 5555dc0104d9aaaa
<< 5555d9091f90044c000001000016aaaa
>> 5555dc0103deaaaa
<< 5555de0a050a050e01800202010050aaaa
...

@MaretArt
Copy link
Author

sure, wait a minute

@MaretArt
Copy link
Author

@MultiMote this the original image:
Image

this full packet exchange log:

SET_LABEL_DENSITY >> 555521010323AAAA
SET_LABEL_DENSITY << 555531010131AAAA
SET_LABEL_TYPE >> 555523010123AAAA
SET_LABEL_TYPE << 555533010133AAAA
START_PRINT >> 555501070001000000000007AAAA
START_PRINT << 555502010102AAAA
START_PAGE_PRINT >> 555503010103AAAA
START_PAGE_PRINT << 555504010104AAAA
SET_DIMENSION >> 55551306018000F0000165AAAA
SET_DIMENSION << 55551402010017AAAA
>> 5555840300000E89AAAA
   55558536000E001300010000000000000000000000000000000000000000000007FFFC0000000003000000000000000000000000000000000000A8AAAA
   55558536000F0024000100000000000000000000000000000000000000000003FFFFFFFF000000060000000000000000000000000000000000009CAAAA
   555585360010002000010000000000000000000000000000000000000000007FFFF0001FF800001C00000000000000000000000000000000000009AAAA
   55558536001100190001000000000000000000000000000000000000000007FFF00000003F80003800000000000000000000000000000000000035AAAA
   5555853600120015000100000000000000000000000000000000000000003FFE0000000001F00070000000000000000000000000000000000000F5AAAA
   555585360013001300010000000000000000000000000000000000000001FFE000000000001E00E000000000000000000000000000000000000052AAAA
   555585360014001000010000000000000000000000000000000000000007FF0000000000000181C00000000000000000000000000000000000000EAAAA
   555585360015000F0001000000000000000000000000000000000000001FF80000000000000061C0000000000000000000000000000000000000EEAAAA
   555585360016000D0001000000000000000000000000000000000000007FE0000000000000000380000000000000000000000000000000000000B5AAAA
   555585360017000E000100000000000000000000000000000000000000FFC000000000000000078000000000000000000000000000000000000013AAAA
   555585360018000F000100000000000000000000000000000000000001FF00000000000000030F0000000000000000000000000000000000000057AAAA
   555585360019000E000100000000000000000000000000000000000003FC00000000000000019E00000000000000000000000000000000000000C5AAAA
   55558536001A001100010000000000000000000000000000000000000FF80000000000000001FE00000000000000000000000000000000000000B1AAAA
   55558536001B004600010000000000000000000000000000000000001FE07FFFF000FFFF9FF8FCFFC00000000000000000000000000000000000C4AAAA
   55558536001C004C00010000000000000000000000000000000000003FC07FFFFC07FFFF9FFCFCFFC00000000000000000000000000000000000C6AAAA
   55558536001D004C00010000000000000000000000000000000000007F807FFFFE0FFFFF9FFC78FFC0000000000000000000000000000000000049AAAA
   55558536001E004F0001000000000000000000000000000000000000FF007FFFFF1FFFFF9FFE71FFC0000000000000000000000000000000000053AAAA
   55558536001F004D0001000000000000000000000000000000000000FE007FFFFF1FFFFF9FFE31FFC0000000000000000000000000000000000011AAAA
   555585360020004F0001000000000000000000000000000000000001FE007FFFFF9FFFFF9FFE23FFC00000000000000000000000000000000000BFAAAA
   55558536002100380002000000000000000000000000000000000001FC007F007FBFE0001FFF03FFC00000000000000000000000000000000000D6AAAA
   55558536002300380001000000000000000000000000000000000003F8007F007FBFC0001FFF07FFC00000000000000000000000000000000000F5AAAA
   55558536002400440001000000000000000000000000000000000003F8007F007FBF83FF9FFF8FFFC000000000000000000000000000000000003AAAAA
   55558536002500440001000000000000000000000000000000000003F0007F00FFBF83FF9FFF8FFFC00000000000000000000000000000000000B3AAAA
   555585360026004D0001000000000000000000000000000000000003F0007FFFFFBF83FF9FFFCFFFC0000000000000000000000000000000000006AAAA
   555585360027004D0002000000000000000000000000000000000003F0007FFFFF3F83FF9FFFDFFFC0000000000000000000000000000000000094AAAA
   55558536002900450001000000000000000000000000000000000001F0007FFFFC3F803F9FEFFFDFC0000000000000000000000000000000000043AAAA
   55558536002A00450001000000000000000000000000000000000001F8007FFFF03FC03F9FEFFFDFC0000000000000000000000000000000000004AAAA
   55558536002B00380001000000000000000000000000000000000000F8007F00003FE03F9FEFFF9FC0000000000000000000000000000000000016AAAA
   55558536002C003E0001000000000000000000000000000000000000FC007F00001FFFFF9FE7FF9FC00000000000000000000000000000000000E4AAAA
   55558536002D003C00020000000000000000000000000000000000007C007F00001FFFFF9FE7FF1FC00000000000000000000000000000000000E4AAAA
   55558536002F003A00010000000000000000000000000000000000003E007F00000FFFFF9FE3FF1FC00000000000000000000000000000000000B5AAAA
   555585360030003900010000000000000000000000000000000000001F007F00000FFFFF9FE3FE1FC0000000000000000000000000000000000089AAAA
   555585360031003500010000000000000000000000000000000000000F007F000003FFFF9FE1FE1FC000000000000000000000000000000000009AAAAA
   555585360032001400010000000000000000000000000000000000000780000000007FFF8000000000000000000000000000000000000000000013AAAA
   5555830E003300040001009700980099009AB7AAAA
   5555830E00340004000100980099009A009BBCAAAA
   5555830C003500030001009A009B009C25AAAA
   5555830C003600030001009C009D009E24AAAA
   555585360037092D0001000000000000000000000000000007E7FC7E0003870007C600E001C38380037700000000000000000000000000000000D3AAAA
   5555853600380A2F0001000000000000000000000000000007F7FC7F000047000FE600E001C3C38003770000000000000000000000000000000067AAAA
   5555853600390B2F0001000000000000000000000000000007FFFC7F800006000FE600E001C3C780037700000000000000000000000000000000AAAAAA
   55558536003A064E08010000000000000000000000000000073860739E7DF73C1C767CFC79C3C79E1F7777C000000000000000000000000000001AAAAA
   55558536003B065B0A01000000000000000000000000000007386073BF7FFF7E1C06FEFEFDC3EF9FBF77EFE0000000000000000000000000000020AAAA
   55558536003C08530701000000000000000000000000000007F8607FB373BF661CF6E6EECDC3EFBBB377CCE000000000000000000000000000007BAAAA
   55558536003D07570801000000000000000000000000000007F0607F3F73F77E1CF6E6E67DC3EDBFF377C7E000000000000000000000000000005FAAAA
   55558536003E035008010000000000000000000000000000070060703370FF761C76E6EEEDC3FDBFF377CEE00000000000000000000000000000AEAAAA
   55558536003F035208010000000000000000000000000000070066707373BFE60E76EEEECDC3BDBBB777ECE0000000000000000000000000000020AAAA
   55558536004003580A010000000000000000000000000000070066703F73F77E0FE67EFEFDC3B99FBF777FE0000000000000000000000000000051AAAA
   555585360041001502010000000000000000000000000000000002001800E030038018182000000E18000300000000000000000000000000000098AAAA
   55558403004211D4AAAA
   5555853600530A000001000000000000000000000000007E1E0000000000000000000000000000000000000000000000000000000000000000008BAAAA
   5555853600541E1C14010001E0F00000007F00000000E1FE1E000000000007C03E03F0030000603E0007C006000FC1FF80000000000000000000B8AAAA
   55558536005526331C010001E0F0000001FF80000078E3FE1E00001E00000FF0FF87F81F0003E07F800FF03E003FE1FF80000000000000000000F8AAAA
   555585360056243E1F010001F0F0000001FFC0000078E3C21E00001E00001FF8FF8FFC7F000FE0FFC01FF0FE003FF1FF80000000000000000000E3AAAA
   5555853600571E3317010001F0F0000003E3C000007803C01E00001E00401C79E3CE1C7F000FE0E3C03C78FE0078F1E00000000000000000000031AAAA
   555585360058423F15010001F8F0FE0003C1C3F0EFFEEFF71E78FE3F81E01C79E3CE1C6F000DE1E3C03C78DE007871E000000000000000000000CCAAAA
   555585360059483C10010001FCF1FF0003E007F8FFFEEFF71EF9FF3F81E01C3DC3CE1E0F0001E1E3C03C381E000071DC0000000000000000000076AAAA
   55558536005A4E3B14010001FCF3FF8001FC0FFCFFFEEFF71FF1EF3F80E03C3DC3DE1E0F0001E1E1C03C381E0000F1FF0000000000000000000069AAAA
   55558536005B433614010001DEF3E78001FE0F3CFE78E3C71FE3CF1E00C03C3DC3DE1E0F0001E0E3C03C381E0000F1FF000000000000000000009BAAAA
   55558536005C3C3415010001DFF3878000FF9E1CF078E3C71FC0071E00003C3DC3DE1E0F0001E0FFC03C381E0001E3EF800000000000000000008AAAAA
   55558536005D3C3910010001CFF38380001FDFFCF078E3C71FC0FF1E00003C3DC3DE1E0F0001E0FFC03C381E0007C00780000000000000000000E3AAAA
   55558536005E3A360F010001C7F383800003DFFCF078E3C71FE1FF1E00001C3DC3CE1E0F0001E07FC03C381E000F8003800000000000000000003FAAAA
   55558536005F372E14010001C7F3838003C1DE00F078E3C71FE3C71E00001C79E3CE1C0F0001E003C03C781E001F03C3800000000000000000003FAAAA
   5555853600603B3116010001C3F3C78803C3CF08F078E3C71EF3C71E00401C79E3CE1C0F0201E007823C781E043E03C78000000000000000000076AAAA
   5555853600614C4B22010001C3F3FF1E03FFCFFCF07EE3C71EFBFF1F81E01FF8FF8FFC0F0781E03F8F1FF01E0F3FFBFF80000000000000000000D0AAAA
   555585360062444320010001C0F1FF1E01FF87FCF07EE3C71E79FF0F81E00FF0FF87F80F0781E03E0F0FF01E0F3FF9FF000000000000000000000FAAAA
   5555853600633B391C010001C0F0FE1E007F03F8F03EE3C71E3CFF8F80E007E07F03F00F0701E03C0707E01E0E3FF8FE0000000000000000000035AAAA
   5555840300640DEEAAAA
   555585360071060C1101000000000000001C000000E0000000000000000003801C0000E00000007000003801C0000E00E00700060000000000003DAAAA
   555585360072132125010001E0F00000007F000000F0000000000000000007C07F00E1F0030070FC00C07C07F00E1F01F81F803E0000000000006DAAAA
   555585360073163337010001E0F0000001FF800000F000000000000000000FF0FF81E7F81F0073FE07C0FF0FF81E7FC7FC3FE0FE000000000000F4AAAA
   555585360074183A3A010001F0F0000001FFC00000F000000000000000001FF9FF81C7FC7F0063FE1FC1FF9FF81C7FC7FE3FE1FE0000000000006CAAAA
   55558536007512352F010001F0F0000003E3C000000000000000000000401C79E3C1CF1E7F00E78F1FC1C79E3C1CF1EF1E79F1F0000000000000F0AAAA
   555585360076283224010001F8F0FE0003C1C3F0EEF000000000000001E01C7803C38F1E7700E78F1BC1C7803C38F1E01E70F3C0000000000000FCAAAA
   5555853600772C2828010001FCF1FF0003E007F8FEF000000000000001E01C3C07C38E1E0700C00F03C1C3C07C38E1E01E70F3BE000000000000F2AAAA
   555585360078322C2F010001FCF3FF8001FC0FFCFEF000000000000000E03C3C3F838E1E0701C01E03C3C3C3F838E1E0FE7873FF00000000000095AAAA
   5555853600792A282E010001DEF3C78000FF0F1CF0F000000000000000003C3C3F070E1E0701C01E03C3C3C3F070E1E0F879F3FF0000000000005CAAAA
   55558536007A2B2830010001CFF38380003F9FFCF0F000000000000000003C3C3F870E1E0701803C03C3C3C3F870E1E0FE3FF3C7800000000000B7AAAA
   55558536007B29252A010001CFF383800007DFFCF0F000000000000000001C3C07C70E1E0703807803C1C3C07C70E1E01E3FF387800000000000E0AAAA
   55558536007C2B2426010001C7F3838003C3DFFCF0F000000000000000001C3803CE0F1E070380F003C1C3803CE0F1E01E0EF38780000000000016AAAA
   55558536007D24272B010001C3F3878003C1DF00F0F000000000000000001C79C3CE0F1E070301E003C1C79C3CE0F1EF1E01E387800000000000F0AAAA
   55558536007E272A2D010001C3F3C78803C3CF08F0F000000000000000401C79C3CE0F1E070703E003C1C79C3CE0F1EF1E03E3C7800000000000ADAAAA
   55558536007F353A3B010001C3F3FF1E03FFCFFCF0F000000000000001E01FF9FFCC07FC070703FF83C1FF9FFCC07FCFFE1FC3FF000000000000A6AAAA
   5555853600802F3436010001C0F1FF1E01FF87FCF0F000000000000001E00FF0FF9C07F8070603FF83C0FF0FF9C07FC7FE1F81FF00000000000099AAAA
   555585360081282E27010001C0F0FE1E007F03F8F0F000000000000000E007E07F1C03F0070E03FF83C07E07F1C03F03F81E00FC00000000000008AAAA
   555585360082000603010000000000000000000000000000000000000000000000380000000E000000000000038000000000000000000000000080AAAA
   5555840300832327AAAA
   5555830C00A60003000100DE00DF00E0CAAAAA
   5555853600A711131C01000000000000000000000000C0FFFE00003E00000000000000000007C003FE00FF00FF00FFF000000000000000000000C1AAAA
   5555853600A814162001000000000000000000000007C0FFFE00003C00000000000000000007C007FF03FF83FF80FFF000000000000000000000F2AAAA
   5555853600A91817230100000000000000000000007FC0FFFE00003C00000000000000000007C00FFF03FF87FFC1FFF000000000000000000000C8AAAA
   5555853600AA191820010000000000000000000000FFC0FFFE00007C00000000000000000003801FDF87CFC7E7C1FFF0000000000000000000009EAAAA
   5555853600AB0F1315010000000000000000000000FFC0007C00007C00000000000000000000001F8F87C7C7C7C1E00000000000000000000000DEAAAA
   5555853600AC101E13010000000000000000000000FFC000FC00007C070001800000038001C0001F0F8F87CF83C1E000000000000000000000000DAAAA
   5555853600AD0D4413010000000000000000000000E7C000F80000FC3FC0F7F0F83C1FE07BCF801E0F8F07CF83C3E0000000000000000000000067AAAA
   5555853600AE0A4A10010000000000000000000000078001F80000F8FFF1FFF0F83C7FF87FCF80000F8F07C007C3CC0000000000000000000000F7AAAA
   5555853600AF094D15010000000000000000000000078001F00000F8FFF1FFF8F87C7FF87FCF80001F1F07C007C7FF000000000000000000000000AAAA
   5555853600B0094617010000000000000000000000078003E00000F9F0F1F9F8F87CFC787FCF00003F1F07C00F87FFC00000000000000000000027AAAA
   5555853600B10B3E180100000000000000000000000F8007E00000F9F0F1F0F8F07CF878FC0F00003E1F07C01F87FFC00000000000000000000008AAAA
   5555853600B20A35150100000000000000000000000F8007C00000F800F1F0F8F07C0078F81F0000FC1F07C07F03C7C0000000000000000000002FAAAA
   5555853600B30A45110100000000000000000000000F800F800001F87FF3F0F9F0783FF8F81F0001F83E0F80FE0003E000000000000000000000DEAAAA
   5555853600B40946110100000000000000000000000F000F800001F1FFF3E0F9F078FFF8F01F0003F03E0F81FC0003E00000000000000000000001AAAA
   5555853600B50948110100000000000000000000000F001F000001F3FFF3E1F1F0F9FFF8F01E0007E03E0F83F80003E00000000000000000000007AAAA
   5555853600B60C42170100000000000000000000000F003E0007C1F3E1F3E1F1F0F9F0F8F01E000FC03E0F87F01F07E000000000000000000000C5AAAA
   5555853600B70D43150100000000000000000000001F003E0007C1F3E1F3E1F1E0F9F0F9F01E001FC03E0F87E00F87C00000000000000000000077AAAA
   5555853600B80D44150100000000000000000000001F003E0007E3F3C1E3E1F1F0F9F0F1F03E003F803E1F0FC00F87C0000000000000000000008DAAAA
   5555853600B90D56240100000000000000000000001F007C0007FFE3E7E3E1F1FFF1F3F1F03E007FFF1FFF1FFF8FFFC000000000000000000000EAAAAA
   5555853600BA0C58230100000000000000000000003E00F80003FFE3FFE7C1F1FFF1FFF1E03E007FFF0FFE3FFF8FFF800000000000000000000011AAAA
   5555853600BB0B53200100000000000000000000003E00F80001FFC1FFE7C1F0FFF0FFF1E03E007FFE0FFC3FFF87FF0000000000000000000000B4AAAA
   5555853600BC0A491A0100000000000000000000003E01F00000FF00FDE7C3E07EF07EF1E03C007FFE07F03FFF81FC000000000000000000000048AAAA
   5555840300BD0B31AAAA
   55558602C70142AAAA
   5555840300C80A45AAAA
   5555853600D23D423B010000FE1CE1DC38F1FF8E063C381C783FF73F80E063C1C01C0EE3C3C73877FEE1DC783FC7FB803C71E381C7878387000039AAAA
   5555853600D345463E010000FF9CF1DE78F1FF8F067C3C1C783FF73FC0F06781C01E0EE783C73C77FEE1DCF03FE7FB803C71E3C1C78783C7000029AAAA
   5555853600D43E3D3A010000E79CF9CE71F83C1F86787C1E78078739E1F06701C03E0EEF03C73E7070E1DCE038E703807E39C7C1E787C3E70000F2AAAA
   5555853600D53F3C3E010000E39CF9CF71F83C1F86F07C1F78078738E1F06E01C03E0EFE03C73E7070E1DFC038E703807E3BC7C1F78FC3E700005BAAAA
   5555853600D63F3E42010000E3DCFDC7E1F83C1B87E06E1F78078738E1B87E01C0370EFE03C73F7070E1DFC038E7F3806E1F86E1F78FE3F7000038AAAA
   5555853600D7443F48010000E3DCFDC7E3DC3C3BC7E0EF1BF8078738E3B87E01C0770EFE03C7377070E1DFC03FE7F380EF1F8EF1BF8EE3F7000097AAAA
   5555853600D8403F44010000E3DCEFC3C39C3C39C7F0E71BF8078738E39C7E01C0738EFE03C733F070E1DFC03FC7F380E70F0E71BF9CF3BF0000AAAAAA
   5555853600D9444544010000E3DCEFC1C3FC3C3FC7F0FF19F8078738E3FC7F01C07F8EFF03C733F070E1DFE03F870380FF0E0FF19F9FF3BF0000ECAAAA
   5555853600DA484441010000E39CE7C1C7FE3C7FE779FF99F8078738E7FC7701C0FF8EEF03C731F070E1DCE038070381FF8E1FF99F9FF39F000063AAAA
   5555853600DB484941010000EF9CE7C1C7FE3C7FE679FF98F807873BCFFC6781C0FF8EE781EF31F070F39CF038070381FF8E1FF98FBFF39F000008AAAA
   5555853600DC3D4A40010000FF1CE3C1CF0E3CF0E63FC3987807873FCF0E63C1FFE1CEE3C1FE30F0707F9C783807FBFFC38E3C3987B87B8F00002CAAAA
   5555853600DD37413B010000FC1CE1C1CE073CE0761F83D87807873F0E0E61C1FFC1EEE1C0FC3070703F1C383807FBFF81CE383D87B83B87000076AAAA
   5555840300DE124BAAAA
END_PAGE_PRINT >> 5555E30101E3AAAA
END_PAGE_PRINT << 5555D30300C70116AAAA5555D30301800150AAAA5555E40101E4AAAA
GET_PRINT_STATUS >> 5555A30101A3AAAA
GET_PRINT_STATUS << 5555B30A00003E00031F0002000099AAAA

@MultiMote
Copy link
Owner

MultiMote commented Feb 16, 2025

I reconstructed your print from packets and it looks like this:

Image

Maybe you need to change your print direction.

BTW, your original image is too big for B1 (this printer has 384 pixels printhead). Are you scaling it down before processing?

@MaretArt
Copy link
Author

MaretArt commented Feb 16, 2025

@MultiMote wow, awesome
i didn't realize that width and height in SET_DIMENSION were swapped.

thanks a lot @MultiMote for everything, now it works normally

@MaretArt
Copy link
Author

Saya merekonstruksi cetakan Anda dari paket-paket dan hasilnya seperti ini:

Image

Mungkin Anda perlu mengubah arah cetak Anda.

BTW, gambar asli Anda terlalu besar untuk B1 (printer ini memiliki printhead 384 piksel). Apakah Anda mengecilkannya sebelum memproses?

on SET_DIMENSION my width and height are swapped. that's all

@MaretArt
Copy link
Author

@MultiMote Oh yeah there's more, how do you know the size of paper used in the printer?
like this:

Image

@MultiMote
Copy link
Owner

MultiMote commented Feb 17, 2025

  1. Send RfidInfo and parse the result.
  2. Make HTTP query using barcode from RfidInfo and read dimensions from the result
POST https://print.niimbot.com/api/template/getCloudTemplateByOneCode HTTP/1.1
Content-Type: application/json
niimbot-user-agent: AppVersionName/999.0.0

{ "oneCode" : "LABEL_BARCODE" }

There is no offline way of doing this known to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants