shtrih-m / javapos_shtrih

Реализация JavaPOS драйвера принтера фискального регистратора для устройств Штрих-М
http://www.shtrih-m.ru
MIT License
33 stars 16 forks source link

До физической перезагрузки принтера всегда вываливается JposException: 213 с ExtendedCode 513 #174

Open alexbayker opened 5 months ago

alexbayker commented 5 months ago

На мобильных кассах Pax A930 (внутри которых именно штриховский принтер, для работы с ним мы используем этот драйвер) при полном разряде кассы и последующем включении кассы на зарядке периодически возникает ситуация, что принтер намертво зависает до достижения 20% заряда (выяснено экспериментально) и последующей аппаратной перезагрузки кассы.

Проблема в том, что мы никак не можем средствами драйвера заставить принтер работать даже после достижения необходимого процента заряда, помогает только полная перезагрузка кассы, после этого принтер начинает работать в штатном режиме.

При попытке установить у объекта val printer: ShtrihFiscalPrinter = ShtrihFiscalPrinter(FiscalPrinter()) значение printer.deviceEnabled = true всегда вываливается ошибка jpos.JposException: 213, Код ошибки D5h (213) от ККТ: Критическая ошибка при загрузке ERR16 (0x10): "ошибка принтера!"

Пробовали вызывать функцию, которая по идее должна перезагружать принтер printer.resetPrinter() , но эта функция требует, что мы предварительно вызвали такой код:

printer.open(logicalName)
printer.claim(3000)
printer.deviceEnabled = true

, и, как я уже написал выше, строка printer.deviceEnabled = true пробрасывает новое исключение, поэтому мы не можем перезагрузить принтер функцией printer.resetPrinter() в такой ситуации.

Пробовал вызывать printer.resetPrinter() раньше выполнения этого кода, но там, при вызове функции printer.resetPrinter(), вываливаются другие ошибки, что должен быть задан claim, и что переменная deviceEnabled должна быть в состоянии true.

Также в драйвере я видел функцию printer.technicalReset(), которая, как я понял из документации, сбрасывает настройки принтера, по сути делая hard reset, но я думаю, что это не то, что нам нужно.

Подскажите, как мы можем выйти из замкнутого круга с цикличным отображением ошибки 213 без перезагрузки кассы? Какие функции драйвера нам вызвать для выполнения тех же действий, что выполняются при физической перезагрузке кассы?

nyxiscoo1 commented 5 months ago

Добрый день.

printer.resetPrinter() не перезагружает принтер, а грубо говоря сбрасывает его состояние до пригодного для печати документов.

Я бы порекомендовал такую последовательность действий:

  1. Проверить не исправлено ли это в свежих версиях КЯ.
  2. Если нет, написать в техподдержку КЯ, что у них баг.
  3. Если вышеперечисленное не помогло самому рестартовать КЯ при неудачном подключении, примерно так:
private void restartCashCore() throws JposException {
    log.debug("Restarting CashCore");

    Intent i = new Intent();
    String cashcorePackageName = "ru.shtrihm.droidcashcore";
    String cashcoreClassName = "ru.shtrihm.droidcashcore.CashcoreService";
    i.setComponent(new ComponentName(cashcorePackageName, cashcoreClassName));
    //i.putExtra("args", etArgs.getText().toString());
    appContext.stopService(i);
    appContext.startService(i);
}

И использовать это можно примерно так:

private ShtrihFiscalPrinter connect() throws Exception {

    final String PRINTER_NAME = "ShtrihFptr";
    final int CLAIM_TIMEOUT = 3000;

    ShtrihFiscalPrinter printer = getShtrihFiscalPrinter();

    try {
        printer.open(PRINTER_NAME);
        printer.claim(CLAIM_TIMEOUT);
        printer.setDeviceEnabled(true);
    } catch (Exception e) {
        printer.close();

        restartCashCore();

        final int MAX_CONNECTION_ATTEMPTS = 5;
        for (int i = 1; i <= MAX_CONNECTION_ATTEMPTS; i++) {
            try {
                log.error("Reconnection attempt #" + i);

                printer = getShtrihFiscalPrinter();
                printer.open(PRINTER_NAME);
                printer.claim(CLAIM_TIMEOUT);
                printer.setDeviceEnabled(true);
                break;
            } catch (Exception exc) {
                log.error("Connection failed, attempt #" + i, exc);
                printer.close();
                if (i == MAX_CONNECTION_ATTEMPTS)
                    throw exc;

                try {
                    Thread.sleep(2000);
                } catch (InterruptedException ignored) {
                    throw exc;
                }
            }
        }
    }

    return printer;
}
alexbayker commented 5 months ago

Попытался вызвать скопированную функцию restartCashCore(), к сожалению, не помогло. Прикладываю логи:

CashCoreLogs: [#8] is running, stopping is ignored!
CashCoreLogs: [#9] is already running, restarting is ignored!
alexbayker commented 5 months ago

Но в целом, кстати, решение рабочее: я вручную остановил приложение CashCore в настройках, затем выполнил restartCashCore() в приложении, и принтер вернулся к работе без перезагрузки кассы. Осталось понять, как все-таки остановить сторонний сервис CashCore из приложения при ошибке 213. Я так понимаю, что какая-то проблема с правами доступа

asem-m commented 5 months ago

При попытке установить у объекта val printer: ShtrihFiscalPrinter = ShtrihFiscalPrinter(FiscalPrinter()) значение printer.deviceEnabled = true всегда вываливается ошибка jpos.JposException: 213, Код ошибки D5h (213) от ККТ: Критическая ошибка при загрузке ERR16 (0x10): "ошибка принтера!"

Печать на кассах Pax A930 осуществляется через библиотеку печати производителя принтера (PAX), она сама решает при каком уровне заряда можно печатать и выдает ошибку в приложение CashCore, если печатать нельзя.

Сообщите какой код ошибки "native err = ?" сообщает библиотека печати в системный лог (logcat) при загрузке CashCore.

В ответе на Короткий запрос состояния ККТ (команда ККТ 10h) в параметре "Напряжение источника питания" возвращается напряжение аккумулятора. В параметре "Напряжение резервной батареи" возвращается значение от 0,00 до 1,00 (100%) - остаточная емкость аккумулятора в процентах.

Также уровень заряда аккумулятора можно получить в Т3П9 "*УРОВЕНЬ ЗАРЯДА АККУМУЛЯТОРА, %".

Если библиотека печати Pax A930 блокирует принтер по уровню заряда аккумулятора, то в Кассовом ПО следует заранее отслеживать уровень заряда аккумулятора и сообщать пользователю кассы о необходимости подключения зарядного устройства к кассе.

Во время оформления фискальных документов перезагружать CashCore нельзя. Перезагрузка CashCore может использоваться в сервисных целях, но не пользователем кассы или Кассовым ПО произвольным образом.

alexbayker commented 5 months ago

При попытке установить у объекта val printer: ShtrihFiscalPrinter = ShtrihFiscalPrinter(FiscalPrinter()) значение printer.deviceEnabled = true всегда вываливается ошибка jpos.JposException: 213, Код ошибки D5h (213) от ККТ: Критическая ошибка при загрузке ERR16 (0x10): "ошибка принтера!"

Печать на кассах Pax A930 осуществляется через библиотеку печати производителя принтера (PAX), она сама решает при каком уровне заряда можно печатать и выдает ошибку в приложение CashCore, если печатать нельзя.

Сообщите какой код ошибки "native err = ?" сообщает библиотека печати в системный лог (logcat) при загрузке CashCore.

В ответе на Короткий запрос состояния ККТ (команда ККТ 10h) в параметре "Напряжение источника питания" возвращается напряжение аккумулятора. В параметре "Напряжение резервной батареи" возвращается значение от 0,00 до 1,00 (100%) - остаточная емкость аккумулятора в процентах.

Также уровень заряда аккумулятора можно получить в Т3П9 "*УРОВЕНЬ ЗАРЯДА АККУМУЛЯТОРА, %".

Если библиотека печати Pax A930 блокирует принтер по уровню заряда аккумулятора, то в Кассовом ПО следует заранее отслеживать уровень заряда аккумулятора и сообщать пользователю кассы о необходимости подключения зарядного устройства к кассе.

Во время оформления фискальных документов перезагружать CashCore нельзя. Перезагрузка CashCore может использоваться в сервисных целях, но не пользователем кассы или Кассовым ПО произвольным образом.

Проблема не в том, что при определенном уровне заряда принтер на кассе перестает работать (логика отображения уведомления для пользователя в таком случае у нас реализована), а в том, что принтер на кассе возвращает ту же ошибку даже после достижения нужного уровня заряда. Помогает только перезагрузка кассы или, как выяснилось выше, перезапуск сервиса CashCore.

Сейчас пытаемся разобраться, как перезапустить сервис CashCore программно.

asem-m commented 5 months ago

Правильное решение для пользователя - это зарядить аккумулятор и перезагрузить кассу, но не сервис CashCore.

Далее настоятельно рекомендовать пользователю не разряжать аккумулятор до критического уровня.

Если Кассовое ПО самостоятельно видит, что критический уровень заряда аккумулятора достигнут, то следует в Кассовом ПО блокировать кассовые операции, а также другие операции, которые требуют печати на ленте, чтобы библиотека печати Pax не заблокировала кассу. В этом случае перезагрузки кассы возможно удасться избежать.

alexbayker commented 5 months ago

К сожалению, ничего не нашлось в логах как по ключевому слову "native", так и по команде "10h"

asem-m commented 5 months ago

К сожалению, ничего не нашлось в логах как по ключевому слову "native", так и по команде "10h"

2024-03-15_17-22 2024-03-15_17-24

alexbayker commented 5 months ago

Такого в логе у меня нет, но нашел что-то подобное, батарея сейчас 94%: 43148/1120436kB 15.03.24 17:33:08.35 30 <HEART> BEAT-224: 14> #0307 FFD1209=2; MemAvailable=min:1073876kB/avmin[256]:1075892kB|av[256]:1105715kB|avmax[256]:1139532kB/max:1151448kB; Battery=94%|8142mV|charge; TCP-socket@11 is open (client=127.0.0.1:42945); 1.17.43148.

asem-m commented 5 months ago

К сожалению, ничего не нашлось в логах как по ключевому слову "native", так и по команде "10h" 2024-03-15_17-22

Это лог загрузки CashCore, который после перезагрузки кассы можно получить.

alexbayker commented 5 months ago

Я как раз и не перезагружаю сейчас кассу потому, что ошибка не будет воспроизводиться, а информация о последней перезагрузке из логов уже затерлась.

asem-m commented 5 months ago

2024-03-16_02-39

Ошибка low voltage, если емкость аккумулятора 1%, если перезагрузить CashCore при емкости 2%, то ошибки нет.

Номер сборки: A930_PayDroid_7.1.1_Virgo_V04.3.28T1_20210615 SW Version: V0.0.0.8

alexbayker commented 5 months ago

Я думаю, что процент заряда, при котором принтер начинает работать, зависит от версии CashCore. И все-таки хотелось, чтобы это работало без перезагрузки именно самой кассы, чтобы перезапуск сервиса выполнялся программно

asem-m commented 5 months ago

Я думаю, что процент заряда, при котором принтер начинает работать, зависит от версии CashCore. И все-таки хотелось, чтобы это работало без перезагрузки именно самой кассы, чтобы перезапуск сервиса выполнялся программно

От версии CashCore не зависит, оно формирует данные для печати и посылает в PAX библиотеку принтера. Если библиотеке что-то не нравится она сообщает ошибку. Если библиотека сообщает в статусе критическую ошибку при загрузке CashCore, то CashCore сообщает критическую ошибку через драйвер в ПО.

В сборке 1.21 CashCore проигнорирует ошибку low voltage при загрузке, но печать будет заблокирована библиотекой печати PAX до тех пор пока напряжение аккумулятора не войдет в допустимый диапазон.

alexbayker commented 5 months ago

Я думаю, что процент заряда, при котором принтер начинает работать, зависит от версии CashCore. И все-таки хотелось, чтобы это работало без перезагрузки именно самой кассы, чтобы перезапуск сервиса выполнялся программно

От версии CashCore не зависит, оно формирует данные для печати и посылает в PAX библиотеку принтера. Если библиотеке что-то не нравится она сообщает ошибку. Если библиотека сообщает в статусе критическую ошибку при загрузке CashCore, то CashCore сообщает критическую ошибку через драйвер в ПО.

В сборке 1.21 CashCore проигнорирует ошибку low voltage при загрузке, но печать будет заблокирована библиотекой печати PAX до тех пор пока напряжение аккумулятора не войдет в допустимый диапазон.

А когда выйдет версия 1.21? Просто в MaxStore сейчас актуальная версия 1.19.43931