Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 7.7 и ранее

v7: Новая поделка ККС - Спарк-130... С какой стороны к нему подобраться из 7.7. - ?

v7: Новая поделка ККС - Спарк-130... С какой стороны к нему подобраться из 7.7. - ?
Я
   MWWRuza
 
01.08.21 - 12:40
Добрый день!
В связи с новыми законами, введением ФФД-1.2 и т.п., мой любимый Спарк-115-Ф перестают поддерживать. Типа, "слабый процессор, малое быстродействие", и т.п. отговорки.
Хотя, это конечно не более чем "отговорки", просто не хотят... Я знаю несколько ККТ других фирм, построенных на том-же "ATmega128A", поддержка ФФД-1.2 в которых заявлена... Чисто маркетинговый ход, на старых бабла собрали, надо новую волну... А поддержать старые, параллельно с выпуском новых - не выгодно, это-же надо прошивку с поддержкой нрового ФФД на старом сертифицировать, а это не выгодно...
Но, что есть, то есть - хорошо хоть комплекты модернизации предусмотрели, для того парка 115-тых, которые в эксплуатации: https://wiki.ccrs.ru/oborudovanie/spark-130/modernizaciya-spark-115f-do-spark-130-f.html
Пришлось купить себе "для опытов" такой ККТ, именно аппарат, не комплект модернизации(их пока не успели наштамповать в достаточном количестве, только к концу августа обещают)...

Короче, сам вопрос: нормальных драйверов на него не удосужились написать, типа работа напрямую с портами, хочешь COM, а хочешь TCP, передавая туда напрямую команды и данные в виде XML... Как это реализовать из 7.7 - ?
Пробовал через CMD и через 1С КомандаСистемы() что-то в него посылать - не получается...  

Из руководства:

"1.    КОМАНДНЫЙ ИНТЕРФЕЙС
ККТ СПАРК-130-Ф (далее – ККТ) обеспечивает обмен командами и данными через СОМ-порт или локальную сеть. СОМ-порт может эмулироваться ККТ на шине USB.
При обмене посредством СОМ-порта, передаваемые команды оформляются в пакет следующей структуры:

Тип    Длина (байт)    Значение
byte    1    02h (STX)
short    2    длина команды (количество байт)
char[]    до 2040    КОМАНДА И ДАННЫЕ (XML)
byte    1    03h (ETX)
byte    1    контрольный байт (LRC)

Контрольный байт является результатом побайтовой операции «ИСКЛЮЧАЮЩЕЕ ИЛИ» (XOR – сложение по модулю 2) всех байтов пакета, кроме контрольного.
Ответные данные от ККТ передаются без байта STX и длины, но дополняются терминальным байтом ETX и контрольным байтом LRC:

Тип    Длина (байт)    Значение
char[]    до 2040    ДАННЫЕ
byte    1    03h (ETX)
byte    1    контрольный байт (LRC)

По локальной сети команды и данные передаются без пакетов, как есть."

Дайте наводку, с какой стороны к нему подобраться? Из его утилиты тестовой, я до него достукиваюсь, через COM, хоть "по кнопочкам", хоть произвольную команду могу посылать, типа как из консоли, поставил программку мониторинга COM-порта, вижу, что в него передается... Но, повторить это из 1С или из командной строки - не получается. Пробовал и просто строки команды передавать, и файл в порт копировать - все не то...

К нему есть так-же библиотека, "SparkLib.dll", реализующа типа эту задачу - но она написана не по технологии COM, в реестре не регистрируется, и из 1С до нее тоже не добраться.
Там к ней есть пример на С++: "const auto instance = LoadLibrary(TEXT("SparkLib.dll"));", но в 1с7.7 так не прокатит... А так, было-бы интересно, из ее описания:

Библиотека SparkLib предоставляет две функции:
Инициализация
int initialize(const INT port, CHAR* response, INT* response_length)
******************
Запрос к ККТ
******************

Что дальше делать, понятно, но ее не загрузить под 7.7...

Доступ на прямую, без библиотек? Через COM-порт, у меня не получилось, через TCP-? То-же не понятно, чувствую, это не WEB-сервер, к которому можно делать POST или GET запросы, это что-то другое...
Толкните в нужном направлении...
Рассказывать что 7.7 устарела и переходи на снеговика, пожалуйста не надо, этот флуд тут не уместен.

PS Кстати, в типовых конфах 8.3 под него есть какой-то драйвер в макете, но, загрузить его в 7.7 то-же не получилось, в том числе и через "UniversalNativeWrapper", падает семерка при попытке загрузки. Да и не хочется мне использовать какой-то"кастрированный" драйвер, через протокол напрямую - интереснее.
   big
 
1 - 02.08.21 - 07:09
ИМХО тут есть несколько вариантов.
1. Написать собственную ВК для работы с СОМ-портом

2. Использовать ВК от Ромикса
Книга знаний: Работа с последовательным (COM, RS-232) портом из 1С:Предприятие 7.7 и 8.0
Сам я с ней не работал, использовал mscomm от Microsoft
3. Использовать функции библиотеки производителя через созданную для таких случаев библиотеку
http://www.script-coding.com/dynwrapx.html


Для мониторинга (работы) с портом попробуй вот эту программу
https://robotchip.ru/terminal-1-9b/
Там сразу виден ответ и весьма широкий функционал.
   big
 
2 - 02.08.21 - 07:13
Вот уже даже для Вин-10 есть доработанный
https://infostart.ru/public/267819/
   MWWRuza
 
3 - 02.08.21 - 11:42
Спасибо, буду думать и пробовать вариант 2 и 3...
Вариант "написать свою ВК" не подходит - нет достаточных знаний и опыта в этом :-(  Кроме 1С, с горем-пополам Дельфи, на уровне чуть дальше, чем "Здравствуй мир!", задача написания собственной ВК, для меня "на уровне фантастики"...

По поводу мониторинга портов - мне вот эта программка понравилась: https://www.hhdsoftware.com/serial-port-monitor
Умеет подключаться к сессии "параллельно", не занимая порт, и в отдельных окошках отображать, что через него пробегает, "и туда, и обратно":
Настройка, чего хотим видеть: https://content.foto.my.mail.ru/mail/m_w_w/_mypagephoto/h-404.jpg
А это, что видим: https://content.foto.my.mail.ru/mail/m_w_w/_mypagephoto/h-403.jpg

На последней картинке, обмен со Спарком из его тестовой утилиты. Сначала нажата кнопочка "Печать", он ни как не отреагировал(потому, что печатать нечего), потом нажата кнопка "Получить документ", его номер по умолчанию "1", потом опять "Печать", ККТ напечатал копию "Отчета о регистрации", потом нажата "Получить документ" с №3, получен "Отчет о состоянии расчетов", и потом опять "Печать", последний док распечатался... В принципе, все видно.
Я вот думаю, а неужели нет каких-то стандартных функций в винде, что-бы из командной строки передать в СОМ-порт то, что нужно, без ВК - ?
Вот фрагмент моих попыток:

Процедура Сформировать()
//    Ком = Симв("02") + "<Print/>";

//    Ком = "02" + "^<Print/^>"; 
//    Ком = "02 08 00 3C 50 72 69 6E 74 2F 3E 03 75";

    Ком = "08 00 3C 50 72 69 6E 74 2F 3E";
//    Ком = Симв("STX") + "<Print/>";

//    Ком = "STX" + "^<Print/^>";
    Ком = "^<Print/^>";
//    ФС.КопироватьФайл("C:\Temp\1.xml",СокрЛП("\\192.168.0.100:8200")+"\1.txt",1); 

    КомандаСистемы("Copy " + Ком + " > COM3");
//    КомандаСистемы("Copy " + "C:\Temp\1.txt" + " > COM3");

//    ФС.КопироватьФайл("C:\Temp\1.txt", "\\192.168.0.100:8200",1);
//    КомандаСистемы("Echo " + Ком + " > COM3"); 

//    КомандаСистемы("Copy " + Ком + " > \\127.0.0.1:8800");
КонецПроцедуры

Естественно, бесполезных, в порт прилетает совсем не то, что нужно...
   big
 
4 - 02.08.21 - 12:25
Ком = "02 08 00 3C 50 72 69 6E 74 2F 3E 03 75"

02 - команда
08 - длина данных в байтах
00 - ?? (1)
3С - 2
50 - 3
72 - 4
69 - 5
6E - 6
74 - 7
2F - 8
3E - 9
03 - конец команды
75 - контрольный разряд.

Получается 9 байт или считается от 0. Хотя я тут не особый специалист.
   Aleksey
 
5 - 02.08.21 - 12:28
Так а какой смысл брать тоже самое? Раз все равно аппарат на свалку не проще ли взять атол или штрих. Или вас под дулом автомата заставляют работать именно с этой кассой?
   MWWRuza
 
6 - 02.08.21 - 14:42
(4) Это последовательность, "подслушенная" монитором порта от команды "по кнопочеке" из тестовой утилиты.
(5) может и проще, был бы он один... А тут, приличный парк... И объяснить клиенту, что это "модернизация" имеющегося, проще, чем то, что надо старый выкинуть на свалку и купить новый, совсем другого произодителя... И плюс к тому, пока мне это интересно.
   MWWRuza
 
7 - 02.08.21 - 23:00
Попробовал через компоненту от Ромикса... Пришлось взять вторую, ту, которая для HEX сделана.
В принципе, монитор порта показывает, что "все красиво"... Но, ККТ даже не дергается :-(
Последовательность действий:
Запустил монитор, подключил(открыл порт) тестовую утилиту, нажал "печать", ККТ отпечатал копию "Отчета о состоянии расчетов". Отключил(закрыл порт).
Запустил 1С, порт открылся. Передал команду(скопировал предыдущую, от теста), в мониторе вижу, что все один в один. Но, касса даже не хрюкнула :-(
Закрыл 1С.
На скриншоте все видно: https://content.foto.my.mail.ru/mail/m_w_w/_mypagephoto/h-405.jpg
На запись - вроде все ОК, совпадает символ-в символ... А в ответ - тишина...
Что я не так делаю?
   MWWRuza
 
8 - 03.08.21 - 00:08
Есть!!! :-)
Пришлось все-таки Дельфи вспоминать(хорошо на нем, а не например на С++ написана), и компоненту заново перекомпилировать...
Все дело в скорости порта. У меня в Спарке - 115200, а в компоненте жестко 9600 прописано было.
Заменил: p_BaudRate:= CBR_9600; на p_BaudRate:= CBR_115200;, перекомпилировал, и начал Спарк отзываться на строку символов: "02 08 00 3C 50 72 69 6E 74 2F 3E 03 75"...
Остается теперь разобраться, как из команды(например) - "<Print/>" получить строку HEX "02 08 00 3C 50 72 69 6E 74 2F 3E 03 75". В принципе, были у меня где-то функции преобразования в HEX, но, тут еще нужно контрольную сумму считать... Пока не понимаю как...
   MWWRuza
 
9 - 03.08.21 - 08:42
Я тут не спеша подумал, по хорошему, надо все эти функции преобразования и кодирования данных внутрь ВК засунуть. Что-бы на входе ловила строки в формате XML, как в мануале прописано, преобразовывала в HEX, а дальше уже все и так работает. По хорошему, и выходные данные надо преобразовывать из HEX в XML. Тогда, получится по сути, полноценный драйвер - ВК под 7.7(привет ККС). Не знаю, справлюсь ли... Но, надо попробовать.
   MWWRuza
 
10 - 03.08.21 - 13:01
(8) а в компоненте жестко 9600 прописано было.
Нет, это видимо значение по умолчанию. Прекрасно и из 1С этот параметр выставляется, можно саму компоненту и не трогать:
rs232.СкоростьПередачи  = 115200;
Работает, даже если внутри скорость на 9600 вернуть.
   MWWRuza
 
11 - 03.08.21 - 13:58
В общем, пока добавлять в компоненту что-то не решаюсь, с наскока не получится, это не скорость по умолчанию подправить...

Сделал почти все на 1С, кроме последнего байта, контрольная сумма:

Функция ЧислоТоХекс(Знач тЗначение, тОснование)
   тРезультат = "";
   Пока тЗначение > 0 Цикл
      тРезультат = Сред("0123456789ABCDEF", тЗначение%тОснование + 1, 1) + тРезультат;
      тЗначение = Цел(тЗначение/тОснование) ;
   КонецЦикла;
   Возврат тРезультат;
КонецФункции

Функция СтрокаТоХекс(ASCII) 
    Результат = "";
       Для Сч = 1 По СтрДлина(ASCII) Цикл 
           Dec = КодСимв(Сред(ASCII,Сч,1));
        Ост = Dec;
        Hex="";
        Пока Ост>0 Цикл
            HEX0 = Ост - Цел(Ост / 16) * 16;
            Ост = Цел(Ост / 16);
            Если HEX0 = 10 Тогда
                HEX0 = "A";
            ИначеЕсли HEX0 = 11 Тогда
                HEX0 = "B"; 
            ИначеЕсли HEX0 =12 Тогда
                HEX0 = "C"; 
            ИначеЕсли HEX0=13 Тогда
                HEX0 = "D"; 
            ИначеЕсли HEX0=14 Тогда
                HEX0 = "E"; 
            ИначеЕсли HEX0=15 Тогда
                HEX0 = "F";
            КонецЕсли;
            Hex = "" + HEX0 + Hex;
        КонецЦикла;
        Результат = Результат + Hex;
    КонецЦикла;    
    Возврат Результат; 
КонецФункции

Функция ВставитьПробелы(Команд)
    ВыхКоманд    = ""; 
    Сч = 0;
    Для Сч = 1 По СтрДлина(Команд) Цикл
        Если Сч%2 = 0 Тогда
            ВыхКоманд = ВыхКоманд + Сред(Команд, Сч - 1, 2) + " ";    
        КонецЕсли;    
    КонецЦикла;
    Возврат ВыхКоманд;    
КонецФункции

Процедура Выполнить()
    Команд        = СокрЛП(СтрокаТоХекс(СокрЛП(ИсхСтр)));
    ДлинаБайт    = СтрДлина(Команд) / 2;
    СтрДлиныКом    = Лев(Прав("00" + ЧислоТоХекс(ДлинаБайт, 16), 2) + "0000", 4);
    Команд        = "02" + СтрДлиныКом + Команд;
    Команд        = Команд + "03";
    Команд        = Команд + "75";             // 75 - контрольная сумма, пока не понимаю, как получить? 

    Команд        = СокрЛП(ВставитьПробелы(Команд));
//    rs232.ЗаписатьСтроку("02 08 00 3C 50 72 69 6E 74 2F 3E 03 75");

    rs232.ЗаписатьСтроку(Команд);
КонецПроцедуры

Так, все работает, но, контрольный байт пока в "готовом виде" передаю, как его расчитать, пока не понимаю...

Из описания: "Контрольный байт является результатом побайтовой операции «ИСКЛЮЧАЮЩЕЕ ИЛИ» (XOR – сложение по модулю 2) всех байтов пакета, кроме контрольного."

Подскажите, как это сделать в 1С -? Может есть функция подходящая?
   arsik
 
12 - 03.08.21 - 14:15
(0) Мне кажется проще по tcp поднять работу. Все таки наверно там развернут вебсервер которому на входе xml давать можно.
   MWWRuza
 
13 - 03.08.21 - 18:18
(12) Может оно и проще, но, не похоже, что-бы там был вебсервер...

Понял я, как считается контрольная сумма... На "пальцах", через BIN, вот так:

Через Исключающее ИЛИ, складывапем последовательно все байты, и получаем результат :-)

00000010 02
00001000 08

00001010
00000000 00

00001010 
00111100 3C

00110110
01010000 50

01100110
01110010 72

00010100
01101001 69

01111101
01101110 6E

00010011
01110100 74

01100111
00101111 2F

01001000
00111110 3E

01110110
00000011 03

01110101 75 - ВОТ!!!

Немного гиморойный алгоритм получается, если на 1С его реализовывать, может есть что-то готовое?
   MWWRuza
 
14 - 03.08.21 - 22:41
Ну, не знаю.... Не нашел я ничего подходящего, пришлось писать самому...
Скорее всего, за такой код нужно руки отбивать, но, я не знаю, как можно XOR для двух HEX чисел из под 7.7 выполнить, не преобразовывая их в двоичные строки...
И не нашел нормального алгоритма, как HEX в двоичные строки преобразовать, кроме как заполнив таблицу соответствия HEX-BIN...
Громоздко получилось, но работает :-)

Перем СзБин;

Процедура ЗаполнитьСзБин()
    СзБин = СоздатьОбъект("СписокЗначений");
    
    СзБин.ДобавитьЗначение("00", "00000000");
    СзБин.ДобавитьЗначение("01", "00000001");
    СзБин.ДобавитьЗначение("02", "00000010");
    СзБин.ДобавитьЗначение("03", "00000011");
    СзБин.ДобавитьЗначение("04", "00000100");
    СзБин.ДобавитьЗначение("05", "00000101");
    СзБин.ДобавитьЗначение("06", "00000110");
    СзБин.ДобавитьЗначение("07", "00000111");
    СзБин.ДобавитьЗначение("08", "00001000");
    СзБин.ДобавитьЗначение("09", "00001001");
    СзБин.ДобавитьЗначение("0A", "00001010");
    СзБин.ДобавитьЗначение("0B", "00001011");
    СзБин.ДобавитьЗначение("0C", "00001100");
    СзБин.ДобавитьЗначение("0D", "00001101");
    СзБин.ДобавитьЗначение("0E", "00001110");
    СзБин.ДобавитьЗначение("0F", "00001111");
    
    СзБин.ДобавитьЗначение("10", "00010000");
    СзБин.ДобавитьЗначение("11", "00010001");
    СзБин.ДобавитьЗначение("12", "00010010");
    СзБин.ДобавитьЗначение("13", "00010011");
    СзБин.ДобавитьЗначение("14", "00010100");
    СзБин.ДобавитьЗначение("15", "00010101");
    СзБин.ДобавитьЗначение("16", "00010110");
    СзБин.ДобавитьЗначение("17", "00010111");
    СзБин.ДобавитьЗначение("18", "00011000");
    СзБин.ДобавитьЗначение("19", "00011001");
    СзБин.ДобавитьЗначение("1A", "00011010");
    СзБин.ДобавитьЗначение("1B", "00011011");
    СзБин.ДобавитьЗначение("1C", "00011100");
    СзБин.ДобавитьЗначение("1D", "00011101");
    СзБин.ДобавитьЗначение("1E", "00011110");
    СзБин.ДобавитьЗначение("1F", "00011111");

    СзБин.ДобавитьЗначение("20", "00100000");
    СзБин.ДобавитьЗначение("21", "00100001");
    СзБин.ДобавитьЗначение("22", "00100010");
    СзБин.ДобавитьЗначение("23", "00100011");
    СзБин.ДобавитьЗначение("24", "00100100");
    СзБин.ДобавитьЗначение("25", "00100101");
    СзБин.ДобавитьЗначение("26", "00100110");
    СзБин.ДобавитьЗначение("27", "00100111");
    СзБин.ДобавитьЗначение("28", "00101000");
    СзБин.ДобавитьЗначение("29", "00101001");
    СзБин.ДобавитьЗначение("2A", "00101010");
    СзБин.ДобавитьЗначение("2B", "00101011");
    СзБин.ДобавитьЗначение("2C", "00101100");
    СзБин.ДобавитьЗначение("2D", "00101101");
    СзБин.ДобавитьЗначение("2E", "00101110");
    СзБин.ДобавитьЗначение("2F", "00101111");

    СзБин.ДобавитьЗначение("30", "00110000");
    СзБин.ДобавитьЗначение("31", "00110001");
    СзБин.ДобавитьЗначение("32", "00110010");
    СзБин.ДобавитьЗначение("33", "00110011");
    СзБин.ДобавитьЗначение("34", "00110100");
    СзБин.ДобавитьЗначение("35", "00110101");
    СзБин.ДобавитьЗначение("36", "00110110");
    СзБин.ДобавитьЗначение("37", "00110111");
    СзБин.ДобавитьЗначение("38", "00111000");
    СзБин.ДобавитьЗначение("39", "00111001");
    СзБин.ДобавитьЗначение("3A", "00111010");
    СзБин.ДобавитьЗначение("3B", "00111011");
    СзБин.ДобавитьЗначение("3C", "00111100");
    СзБин.ДобавитьЗначение("3D", "00111101");
    СзБин.ДобавитьЗначение("3E", "00111110");
    СзБин.ДобавитьЗначение("3F", "00111111");

    СзБин.ДобавитьЗначение("40", "01000000");
    СзБин.ДобавитьЗначение("41", "01000001");
    СзБин.ДобавитьЗначение("42", "01000010");
    СзБин.ДобавитьЗначение("43", "01000011");
    СзБин.ДобавитьЗначение("44", "01000100");
    СзБин.ДобавитьЗначение("45", "01000101");
    СзБин.ДобавитьЗначение("46", "01000110");
    СзБин.ДобавитьЗначение("47", "01000111");
    СзБин.ДобавитьЗначение("48", "01001000");
    СзБин.ДобавитьЗначение("49", "01001001");
    СзБин.ДобавитьЗначение("4A", "01001010");
    СзБин.ДобавитьЗначение("4B", "01001011");
    СзБин.ДобавитьЗначение("4C", "01001100");
    СзБин.ДобавитьЗначение("4D", "01001101");
    СзБин.ДобавитьЗначение("4E", "01001110");
    СзБин.ДобавитьЗначение("4F", "01001111");

    СзБин.ДобавитьЗначение("50", "01010000");
    СзБин.ДобавитьЗначение("51", "01010001");
    СзБин.ДобавитьЗначение("52", "01010010");
    СзБин.ДобавитьЗначение("53", "01010011");
    СзБин.ДобавитьЗначение("54", "01010100");
    СзБин.ДобавитьЗначение("55", "01010101");
    СзБин.ДобавитьЗначение("56", "01010110");
    СзБин.ДобавитьЗначение("57", "01010111");
    СзБин.ДобавитьЗначение("58", "01011000");
    СзБин.ДобавитьЗначение("59", "01011001");
    СзБин.ДобавитьЗначение("5A", "01011010");
    СзБин.ДобавитьЗначение("5B", "01011011");
    СзБин.ДобавитьЗначение("5C", "01011100");
    СзБин.ДобавитьЗначение("5D", "01011101");
    СзБин.ДобавитьЗначение("5E", "01011110");
    СзБин.ДобавитьЗначение("5F", "01011111");

    СзБин.ДобавитьЗначение("60", "01100000");
    СзБин.ДобавитьЗначение("61", "01100001");
    СзБин.ДобавитьЗначение("62", "01100010");
    СзБин.ДобавитьЗначение("63", "01100011");
    СзБин.ДобавитьЗначение("64", "01100100");
    СзБин.ДобавитьЗначение("65", "01100101");
    СзБин.ДобавитьЗначение("66", "01100110");
    СзБин.ДобавитьЗначение("67", "01100111");
    СзБин.ДобавитьЗначение("68", "01101000");
    СзБин.ДобавитьЗначение("69", "01101001");
    СзБин.ДобавитьЗначение("6A", "01101010");
    СзБин.ДобавитьЗначение("6B", "01101011");
    СзБин.ДобавитьЗначение("6C", "01101100");
    СзБин.ДобавитьЗначение("6D", "01101101");
    СзБин.ДобавитьЗначение("6E", "01101110");
    СзБин.ДобавитьЗначение("6F", "01101111");

    СзБин.ДобавитьЗначение("70", "01110000");
    СзБин.ДобавитьЗначение("71", "01110001");
    СзБин.ДобавитьЗначение("72", "01110010");
    СзБин.ДобавитьЗначение("73", "01110011");
    СзБин.ДобавитьЗначение("74", "01110100");
    СзБин.ДобавитьЗначение("75", "01110101");
    СзБин.ДобавитьЗначение("76", "01110110");
    СзБин.ДобавитьЗначение("77", "01110111");
    СзБин.ДобавитьЗначение("78", "01111000");
    СзБин.ДобавитьЗначение("79", "01111001");
    СзБин.ДобавитьЗначение("7A", "01111010");
    СзБин.ДобавитьЗначение("7B", "01111011");
    СзБин.ДобавитьЗначение("7C", "01111100");
    СзБин.ДобавитьЗначение("7D", "01111101");
    СзБин.ДобавитьЗначение("7E", "01111110");
    СзБин.ДобавитьЗначение("7F", "01111111");

    СзБин.ДобавитьЗначение("80", "10000000");
    СзБин.ДобавитьЗначение("81", "10000001");
    СзБин.ДобавитьЗначение("82", "10000010");
    СзБин.ДобавитьЗначение("83", "10000011");
    СзБин.ДобавитьЗначение("84", "10000100");
    СзБин.ДобавитьЗначение("85", "10000101");
    СзБин.ДобавитьЗначение("86", "10000110");
    СзБин.ДобавитьЗначение("87", "10000111");
    СзБин.ДобавитьЗначение("88", "10001000");
    СзБин.ДобавитьЗначение("89", "10001001");
    СзБин.ДобавитьЗначение("8A", "10001010");
    СзБин.ДобавитьЗначение("8B", "10001011");
    СзБин.ДобавитьЗначение("8C", "10001100");
    СзБин.ДобавитьЗначение("8D", "10001101");
    СзБин.ДобавитьЗначение("8E", "10001110");
    СзБин.ДобавитьЗначение("8F", "10001111");

    СзБин.ДобавитьЗначение("90", "10010000");
    СзБин.ДобавитьЗначение("91", "10010001");
    СзБин.ДобавитьЗначение("92", "10010010");
    СзБин.ДобавитьЗначение("93", "10010011");
    СзБин.ДобавитьЗначение("94", "10010100");
    СзБин.ДобавитьЗначение("95", "10010101");
    СзБин.ДобавитьЗначение("96", "10010110");
    СзБин.ДобавитьЗначение("97", "10010111");
    СзБин.ДобавитьЗначение("98", "10011000");
    СзБин.ДобавитьЗначение("99", "10011001");
    СзБин.ДобавитьЗначение("9A", "10011010");
    СзБин.ДобавитьЗначение("9B", "10011011");
    СзБин.ДобавитьЗначение("9C", "10011100");
    СзБин.ДобавитьЗначение("9D", "10011101");
    СзБин.ДобавитьЗначение("9E", "10011110");
    СзБин.ДобавитьЗначение("9F", "10011111");

    СзБин.ДобавитьЗначение("A0", "10100000");
    СзБин.ДобавитьЗначение("A1", "10100001");
    СзБин.ДобавитьЗначение("A2", "10100010");
    СзБин.ДобавитьЗначение("A3", "10100011");
    СзБин.ДобавитьЗначение("A4", "10100100");
    СзБин.ДобавитьЗначение("A5", "10100101");
    СзБин.ДобавитьЗначение("A6", "10100110");
    СзБин.ДобавитьЗначение("A7", "10100111");
    СзБин.ДобавитьЗначение("A8", "10101000");
    СзБин.ДобавитьЗначение("A9", "10101001");
    СзБин.ДобавитьЗначение("AA", "10101010");
    СзБин.ДобавитьЗначение("AB", "10101011");
    СзБин.ДобавитьЗначение("AC", "10101100");
    СзБин.ДобавитьЗначение("AD", "10101101");
    СзБин.ДобавитьЗначение("AE", "10101110");
    СзБин.ДобавитьЗначение("AF", "10101111");

    СзБин.ДобавитьЗначение("B0", "10110000");
    СзБин.ДобавитьЗначение("B1", "10110001");
    СзБин.ДобавитьЗначение("B2", "10110010");
    СзБин.ДобавитьЗначение("B3", "10110011");
    СзБин.ДобавитьЗначение("B4", "10110100");
    СзБин.ДобавитьЗначение("B5", "10110101");
    СзБин.ДобавитьЗначение("B6", "10110110");
    СзБин.ДобавитьЗначение("B7", "10110111");
    СзБин.ДобавитьЗначение("B8", "10111000");
    СзБин.ДобавитьЗначение("B9", "10111001");
    СзБин.ДобавитьЗначение("BA", "10111010");
    СзБин.ДобавитьЗначение("BB", "10111011");
    СзБин.ДобавитьЗначение("BC", "10111100");
    СзБин.ДобавитьЗначение("BD", "10111101");
    СзБин.ДобавитьЗначение("BE", "10111110");
    СзБин.ДобавитьЗначение("BF", "10111111");

    СзБин.ДобавитьЗначение("C0", "11000000");
    СзБин.ДобавитьЗначение("C1", "11000001");
    СзБин.ДобавитьЗначение("C2", "11000010");
    СзБин.ДобавитьЗначение("C3", "11000011");
    СзБин.ДобавитьЗначение("C4", "11000100");
    СзБин.ДобавитьЗначение("C5", "11000101");
    СзБин.ДобавитьЗначение("C6", "11000110");
    СзБин.ДобавитьЗначение("C7", "11000111");
    СзБин.ДобавитьЗначение("C8", "11001000");
    СзБин.ДобавитьЗначение("C9", "11001001");
    СзБин.ДобавитьЗначение("CA", "11001010");
    СзБин.ДобавитьЗначение("CB", "11001011");
    СзБин.ДобавитьЗначение("CC", "11001100");
    СзБин.ДобавитьЗначение("CD", "11001101");
    СзБин.ДобавитьЗначение("CE", "11001110");
    СзБин.ДобавитьЗначение("CF", "11001111");

    СзБин.ДобавитьЗначение("D0", "11010000");
    СзБин.ДобавитьЗначение("D1", "11010001");
    СзБин.ДобавитьЗначение("D2", "11010010");
    СзБин.ДобавитьЗначение("D3", "11010011");
    СзБин.ДобавитьЗначение("D4", "11010100");
    СзБин.ДобавитьЗначение("D5", "11010101");
    СзБин.ДобавитьЗначение("D6", "11010110");
    СзБин.ДобавитьЗначение("D7", "11010111");
    СзБин.ДобавитьЗначение("D8", "11011000");
    СзБин.ДобавитьЗначение("D9", "11011001");
    СзБин.ДобавитьЗначение("DA", "11011010");
    СзБин.ДобавитьЗначение("DB", "11011011");
    СзБин.ДобавитьЗначение("DC", "11011100");
    СзБин.ДобавитьЗначение("DD", "11011101");
    СзБин.ДобавитьЗначение("DE", "11011110");
    СзБин.ДобавитьЗначение("DF", "11011111");

    СзБин.ДобавитьЗначение("E0", "11100000");
    СзБин.ДобавитьЗначение("E1", "11100001");
    СзБин.ДобавитьЗначение("E2", "11100010");
    СзБин.ДобавитьЗначение("E3", "11100011");
    СзБин.ДобавитьЗначение("E4", "11100100");
    СзБин.ДобавитьЗначение("E5", "11100101");
    СзБин.ДобавитьЗначение("E6", "11100110");
    СзБин.ДобавитьЗначение("E7", "11100111");
    СзБин.ДобавитьЗначение("E8", "11101000");
    СзБин.ДобавитьЗначение("E9", "11101001");
    СзБин.ДобавитьЗначение("EA", "11101010");
    СзБин.ДобавитьЗначение("EB", "11101011");
    СзБин.ДобавитьЗначение("EC", "11101100");
    СзБин.ДобавитьЗначение("ED", "11101101");
    СзБин.ДобавитьЗначение("EE", "11101110");
    СзБин.ДобавитьЗначение("EF", "11101111");

    СзБин.ДобавитьЗначение("F0", "11110000");
    СзБин.ДобавитьЗначение("F1", "11110001");
    СзБин.ДобавитьЗначение("F2", "11110010");
    СзБин.ДобавитьЗначение("F3", "11110011");
    СзБин.ДобавитьЗначение("F4", "11110100");
    СзБин.ДобавитьЗначение("F5", "11110101");
    СзБин.ДобавитьЗначение("F6", "11110110");
    СзБин.ДобавитьЗначение("F7", "11110111");
    СзБин.ДобавитьЗначение("F8", "11111000");
    СзБин.ДобавитьЗначение("F9", "11111001");
    СзБин.ДобавитьЗначение("FA", "11111010");
    СзБин.ДобавитьЗначение("FB", "11111011");
    СзБин.ДобавитьЗначение("FC", "11111100");
    СзБин.ДобавитьЗначение("FD", "11111101");
    СзБин.ДобавитьЗначение("FE", "11111110");
    СзБин.ДобавитьЗначение("FF", "11111111");    
КонецПроцедуры    

Функция ЧислоТоХекс(Знач тЗначение, тОснование)
   тРезультат = "";
   Пока тЗначение > 0 Цикл
      тРезультат = Сред("0123456789ABCDEF", тЗначение%тОснование + 1, 1) + тРезультат;
      тЗначение = Цел(тЗначение/тОснование) ;
   КонецЦикла;
   Возврат тРезультат;
КонецФункции

Функция СтрокаТоХекс(ASCII) 
    Результат = "";
       Для Сч = 1 По СтрДлина(ASCII) Цикл 
           Dec = КодСимв(Сред(ASCII,Сч,1));
        Ост = Dec;
        Hex="";
        Пока Ост>0 Цикл
            HEX0 = Ост - Цел(Ост / 16) * 16;
            Ост = Цел(Ост / 16);
            Если HEX0 = 10 Тогда
                HEX0 = "A";
            ИначеЕсли HEX0 = 11 Тогда
                HEX0 = "B"; 
            ИначеЕсли HEX0 =12 Тогда
                HEX0 = "C"; 
            ИначеЕсли HEX0=13 Тогда
                HEX0 = "D"; 
            ИначеЕсли HEX0=14 Тогда
                HEX0 = "E"; 
            ИначеЕсли HEX0=15 Тогда
                HEX0 = "F";
            КонецЕсли;
            Hex = "" + HEX0 + Hex;
        КонецЦикла;
        Результат = Результат + Hex;
    КонецЦикла;    
    Возврат Результат; 
КонецФункции

Функция ВставитьПробелы(Команд)
    ВыхКоманд    = ""; 
    Сч = 0;
    Для Сч = 1 По СтрДлина(Команд) Цикл
        Если Сч%2 = 0 Тогда
            ВыхКоманд = ВыхКоманд + Сред(Команд, Сч - 1, 2) + " ";    
        КонецЕсли;    
    КонецЦикла;
    Возврат ВыхКоманд;    
КонецФункции

Функция ПеревестиХексВБин(Хекс)
    Поз = СзБин.НайтиЗначение(Хекс);
    Если Поз > 0 Тогда
        Бин = "";
        СзБин.ПолучитьЗначение(Поз, Бин);
        Возврат Бин;
    КонецЕсли;    
КонецФункции

Функция XOR(Бит1, Бит2)
    Если ((Бит1 = "0") и (Бит2 = "0")) Или ((Бит1 = "1") и (Бит2 ="1")) Тогда
        Возврат "0";
    Иначе
        Возврат "1";    
    КонецЕсли;    
КонецФункции    

Функция Сложить2ЧислаXOR(Число1Бин, Число2Бин)                                                                   
    Рез = "";
    Для Сч = 1 По 8 Цикл
        Бит1    = Сред(Число1Бин, Сч, 1);
        Бит2    = Сред(Число2Бин, Сч, 1);
        Рез        = Рез + XOR(Бит1, Бит2);
    КонецЦикла;
    Возврат Рез;    
КонецФункции

Функция РасчитатьКС(Команд)
    КомДлина    = СтрДлина(Команд);
    ОстКом        = Команд;
    КСБин        = "00000000";
    Если КомДлина > 0 Тогда
        ДлОст             = КомДлина;
        Для Сч = 1 По ДлОст Цикл
            Если Сч = 2 Тогда
                НовБит     = Лев(ОстКом, 2);
                ОстКом    = Сред(ОстКом, 3);
                ДлОст    = СтрДлина(ОстКом);
                КСБин     = Сложить2ЧислаXOR(КСБин, ПеревестиХексВБин(НовБит));
                Сч = 0; 
                Если ДлОст = 0 Тогда
                    Прервать;
                КонецЕсли;    
                Продолжить;
            КонецЕсли;    
        КонецЦикла;    
    КонецЕсли;
    Возврат СзБин.Получить(КСБин);
КонецФункции    

Процедура Выполнить()
    Команд        = СокрЛП(СтрокаТоХекс(СокрЛП(ИсхСтр)));
    ДлинаБайт    = СтрДлина(Команд) / 2;
    СтрДлиныКом    = Лев(Прав("00" + ЧислоТоХекс(ДлинаБайт, 16), 2) + "0000", 4);
    Команд        = "02" + СтрДлиныКом + Команд;
    Команд        = Команд + "03";
    Команд        = Команд + РасчитатьКС(Команд);
    Команд        = СокрЛП(ВставитьПробелы(Команд));
//    rs232.ЗаписатьСтроку("02 08 00 3C 50 72 69 6E 74 2F 3E 03 75"); 

//    Сообщить("Команда " + Команд);
    rs232.ЗаписатьСтроку(Команд);
КонецПроцедуры

Процедура ПриОткрытии()
    ЗаполнитьСзБин();
КонецПроцедуры    

Печатает, вполне адекватно... Теперь осталось придумать, как из двоичной последовательности, прилетающей в ответ, строку XML получить, и в принципе, можно демку под работу Спарк-130 из 7.7 делать.
Как говорится - на зло врагам! :-)))
   big
 
15 - 04.08.21 - 06:48
(14) Коллега, иногда все-таки надо поискать получше ;)
http://my1c-archive.narod.ru/knowhow/uni_conv.html

з.ы. сам пристыдился за свой дерьмокод, когда это нашёл ))
   MWWRuza
 
16 - 04.08.21 - 07:44
Немного не понял... Это я видел, но, это же из/в любой в десятичную... А мне нужно было из хекс в двоичную... Не то немного.
   MWWRuza
 
17 - 04.08.21 - 07:48
Кстати, разбор ответов я вчера сделал - там все просто, из хекс байты преобразую в десятичные числа, и функцией Симв() получаю символы строки. Работает...
   MWWRuza
 
18 - 04.08.21 - 07:56
А по поводу своей функции, можно конечно было через два вложенных цикла заполнять таблицу соответствий по 16 значениям "матрицы", код будет компактнее на много, но быстродействие - не факт... Тут это где-то обсуждалось уже.
   MWWRuza
 
19 - 04.08.21 - 10:46
В обшем, громоздкую процедуру заполнения списка соответствий HEX-BIN все-таки переделал на циклы, получилось весьма компактно:

Перем СзБин;

Процедура ЗаполнитьСзБинЦикл()
    СзБин     = СоздатьОбъект("СписокЗначений");
    Матр    = СоздатьОбъект("СписокЗначений");
    
    Матр.ДобавитьЗначение("0", "0000");
    Матр.ДобавитьЗначение("1", "0001");
    Матр.ДобавитьЗначение("2", "0010");
    Матр.ДобавитьЗначение("3", "0011");
    Матр.ДобавитьЗначение("4", "0100");
    Матр.ДобавитьЗначение("5", "0101");
    Матр.ДобавитьЗначение("6", "0110");
    Матр.ДобавитьЗначение("7", "0111");
    Матр.ДобавитьЗначение("8", "1000");
    Матр.ДобавитьЗначение("9", "1001");
    Матр.ДобавитьЗначение("A", "1010");
    Матр.ДобавитьЗначение("B", "1011");
    Матр.ДобавитьЗначение("C", "1100");
    Матр.ДобавитьЗначение("D", "1101");
    Матр.ДобавитьЗначение("E", "1110");
    Матр.ДобавитьЗначение("F", "1111");

    Для Сч = 1 По 16 Цикл
        СтрСтБин     = "";
        СтБит     = Матр.ПолучитьЗначение(Сч, СтрСтБин);        
        Для Сч2 = 1 По 16 Цикл
            СтрМлБин     = "";
            МлБит     = Матр.ПолучитьЗначение(Сч2, СтрМлБин);
            СзБин.ДобавитьЗначение(СтБит + МлБит, СтрСтБин + СтрМлБин);
        КонецЦикла;    
    КонецЦикла;    
КонецПроцедуры

Но, это дела не меняет, просто код красивее :-) Заполняется этот список один раз, при открытии формы, так, что, пофик.
   MWWRuza
 
20 - 04.08.21 - 11:08
Короче, это все лирика, как код написать - дело "религии", главное работает...

Вылезла другая проблема. Почему-то ответ от ККТ делится на отдельные строки, на СкринШоте виден ответ на запрос состояния ФН:

https://content.foto.my.mail.ru/mail/m_w_w/_mypagephoto/h-406.jpg

Такое ощущение, что компонента от Ромикса, генерит несколько "ВнешнихСобытий", разбивая полученную из порта строку на отдельные куски, под каждый кусок - свое событие...

PS Может оно так и правильнее, иначе строка может превысить пределы длины строки в 7.7, но... Надо подумать, как из этого "безобразия" валидный XML получить...
   MWWRuza
 
21 - 04.08.21 - 11:58
+(20) Нашел, где в компоненте это ограничение. Да, действительно 100 байт стояло. Увеличил для эксперимента до 1000, перекомпилировал - работает, вот XMLка из одной строки полученная:

https://content.foto.my.mail.ru/mail/m_w_w/_mypagephoto/h-407.jpg

Вопрос - а какое ограничение в 1с77 на длину строки? что-бы не нарваться на "Строка превысила допустимые размеры"-? "Допустимые", это какие?
   big
 
22 - 04.08.21 - 13:15
(21) Ограничение на длину строки в окне сообщений, а так то вроде ни разу не сталкивался.
   MWWRuza
 
23 - 04.08.21 - 13:25
Ясно, спасибо.
Ну, "туда", по описанию протокола: "char[]    до 2040    КОМАНДА И ДАННЫЕ (XML)", - в принципе, это довольно много, хватит на все. Многострочные таблицы чеков, каждая строка как отдельная команда передается, так, что, тут ограничений не должно быть.
А обратно, чтение ответов, там ответы на команды, даже с данными, думаю, 1000 должно хватить. По крайней мере, знаю, где это в компоненте поправить.
На длину строки при записи в порт, в компоненте вроде ограничений я не нашел.
   Злопчинский
 
24 - 04.08.21 - 14:29
(21) как правильно ответили - это в окне сообщений только.
а так - длина строки = 32Кб
   MWWRuza
 
25 - 04.08.21 - 19:58
(24) Спасибо. Отлично, это огромный запас на все "художества", что-бы там не придумали законотворцы :-)))


Список тем форума
 
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.