Нужно отладить код. Прием СМС с парсингом суммы.
- Войдите на сайт для отправки комментариев
Пнд, 14/06/2021 - 16:52
Довелось связаться с недобросовестным исполнителем, который написал кривой код, а на отладке слился.
Идея такова: СМС от сбербанка приходит на sim800l, нужно из текста СМС вытянуть сумму зачисления.
Сейчас код работает, но нестабильно. Если прислать несколько СМС подряд - вообще виснет. Есть мнение, что это из-за использования стрингов.
Вот кусок кода именно с приемом СМС.
001 | #include <SoftwareSerial.h> |
002 |
003 | SoftwareSerial gsm(8, 9); // RX, TX |
004 |
005 | unsigned long tm = 0, cur = 0; |
006 | bool flag = 0, reg = 1; |
007 | String msg = "" ; |
008 |
009 | void setup () { |
010 | Serial .begin(9600); |
011 | gsm.begin(19200); |
012 | gsm.flush(); |
013 | gsm.println( "at+cmgf=1;&W" );delay(100); |
014 | gsm.println( "at+cscs=\"gsm\";&W" );delay(100); |
015 | } |
016 |
017 | void loop () { |
018 | if (reg) { |
019 | reg = 0; |
020 | gsm.println( "at+cmgl=\"rec unread\"" ); |
021 | delay(10); |
022 | } |
023 | if (gsm.available()) { |
024 | char inChar = gsm.read(); |
025 | //Serial.write(inChar); |
026 | msg += inChar; |
027 | /*tm = millis(); |
028 | msg = ""; |
029 | do { |
030 | cur = millis(); |
031 | if (gsm.available()) { |
032 | char inChar = gsm.read(); |
033 | msg += inChar; |
034 | } |
035 | /*Serial.print(" "); |
036 | Serial.print(inChar, HEX); |
037 | Serial.print(" ");*/ |
038 | tm = millis(); |
039 | flag = 1; |
040 | } |
041 | if (flag && millis() - tm >= 7000) { |
042 | flag = 0; |
043 | msg.toLowerCase(); |
044 | //Serial.println("MSG:" + msg); |
045 | |
046 | if (msg.indexOf( "+cmti: \"sm\"" ) != -1 || msg.indexOf( "+cmti: \"me\"" ) != -1) { |
047 | gsm.println( "at+cmgl=\"rec unread\"" ); |
048 | delay(10); |
049 | } |
050 | if (msg.indexOf( "at+cmgl=\"rec unread\"" ) != -1) { |
051 | String line = "" ; |
052 | byte row = 0; |
053 | for ( int i = 0; i < msg.length(); i++) { |
054 | line += msg[i]; |
055 | if (msg[i] == '\n' ) { |
056 | //Serial.println("row:" + String(row) + " str=" + line); |
057 | row++; |
058 | if (reg) { |
059 | reg = 0; |
060 | Serial .println(UCS2ToString(line)); |
061 | String money = UCS2ToString(line); |
062 | if (money.indexOf( "аеревад " ) != -1) { |
063 | money = money.substring(money.indexOf( "аеревад " ) + 14, money.indexOf( "р Б" )); |
064 | //Serial.println("money:" + money); |
065 | } else if (money.indexOf( "зачисаеаие " ) != -1) { |
066 | money = money.substring(money.indexOf( "зачисаеаие " ) + 20, money.indexOf( "р Б" )); |
067 | //Serial.println("money:" + money); |
068 | } |
069 | Serial .println( "money:" + String(money.toInt())); |
070 | gsm.println( "at+cmgda=\"del read\"" ); |
071 | } |
072 | if (line.indexOf( "+cmgl:" ) != -1) { |
073 | reg = 1; |
074 | } |
075 | line = "" ; |
076 | } |
077 | } |
078 | } |
079 | |
080 | msg = "" ; |
081 | } |
082 | if ( Serial .available()) { |
083 | //while (Serial.available() > 0) |
084 | gsm.write( Serial .read()); |
085 | } |
086 | } |
087 |
088 | String UCS2ToString(String s) { // Функция декодирования UCS2 строки |
089 | String result = "" ; |
090 | unsigned char c[5] = "" ; // Массив для хранения результата |
091 | for ( int i = 0; i < s.length() - 3; i += 4) { // Перебираем по 4 символа кодировки |
092 | unsigned long code = (((unsigned int )HexSymbolToChar(s[i])) << 12) + // Получаем UNICODE-код символа из HEX представления |
093 | (((unsigned int )HexSymbolToChar(s[i + 1])) << 8) + |
094 | (((unsigned int )HexSymbolToChar(s[i + 2])) << 4) + |
095 | ((unsigned int )HexSymbolToChar(s[i + 3])); |
096 | if (code <= 0x7F) { // Теперь в соответствии с количеством байт формируем символ |
097 | c[0] = ( char )code; |
098 | c[1] = 0; // Не забываем про завершающий ноль |
099 | } else if (code <= 0x7FF) { |
100 | c[0] = ( char )(0xC0 | (code >> 6)); |
101 | c[1] = ( char )(0x80 | (code & 0x3F)); |
102 | c[2] = 0; |
103 | } else if (code <= 0xFFFF) { |
104 | c[0] = ( char )(0xE0 | (code >> 12)); |
105 | c[1] = ( char )(0x80 | ((code >> 6) & 0x3F)); |
106 | c[2] = ( char )(0x80 | (code & 0x3F)); |
107 | c[3] = 0; |
108 | } else if (code <= 0x1FFFFF) { |
109 | c[0] = ( char )(0xE0 | (code >> 18)); |
110 | c[1] = ( char )(0xE0 | ((code >> 12) & 0x3F)); |
111 | c[2] = ( char )(0x80 | ((code >> 6) & 0x3F)); |
112 | c[3] = ( char )(0x80 | (code & 0x3F)); |
113 | c[4] = 0; |
114 | } |
115 | result += String(( char *)c); // Добавляем полученный символ к результату |
116 | } |
117 | return (result); |
118 | } |
119 |
120 | unsigned char HexSymbolToChar( char c) { |
121 | if ((c >= 0x30) && (c <= 0x39)) return (c - 0x30); |
122 | else if ((c >= 'A' ) && (c <= 'F' )) return (c - 'A' + 10); |
123 | else return (0); |
124 | } |
Ищу исполнителя, готового довести до ума этот проект
напишу заново корректно работающий скетч. 2000р, предоплата 50%, man9913@mail.ru
Где то год назад, пытались договориться со сбером, присылать в обратном квитке при оплате через телефон не имя отчество и букву фамилии, а номер телефона с которого был осуществлен перевод суммы. Получили отказ. Хотя всё ПО уже было написано под 590 модем. А идея была классная - автоматизация оплаты услуги, с пробитием (фискализацией) чека на конкретного человека и отсылки ему на телефон QRcoda или SMS от ОФД. Так жаль потраченных ресурсов. Это действие со стороны сбера даже не попадало под 157-ФЗ, сначала вроде согласились подумать, но потом, наверно, сказали себе, что нам и так не плохо живется, зачем делать какие то телодвижения. И очередной раз плюнули на просьбу общественности. Ур-ы.
Где то год назад, пытались договориться со сбером, присылать в обратном квитке при оплате через телефон не имя отчество и букву фамилии, а номер телефона с которого был осуществлен перевод суммы. Получили отказ. Хотя всё ПО уже было написано под 590 модем. А идея была классная - автоматизация оплаты услуги, с пробитием (фискализацией) чека на конкретного человека и отсылки ему на телефон QRcoda или SMS от ОФД. Так жаль потраченных ресурсов. Это действие со стороны сбера даже не попадало под 157-ФЗ, сначала вроде согласились подумать, но потом, наверно, сказали себе, что нам и так не плохо живется, зачем делать какие то телодвижения. И очередной раз плюнули на просьбу общественности. Ур-ы.
Уговаривал их слать СМС на транслите (типа старый телефон у меня) - не хотят. А фискализация мне не нужна ("уплачиваю" НПД).
Есть лайфхак - нужно к сберкарте привязать два номера телефона. При переводе на номер "1", на него приходит полный текст с отправителем и т.д. Номер "2" получает только СМС "зачисление 100500 рублей". Так для работы достаточно оперировать только с одним типом сообщений.
Да хоть 10 номеров привязывай к карте. Для того, чтобы не печатать чек на бумажном носителе, ты должен этот чек привязать к конкретному клиенту (даже полное ФИО не катит). И при передаче чека к ОФД предоставить либо номер телефона данного человека, либо адрес его электронной почты. Никто, естественно, из клиентов не будет предоставлять таких данных о своём телефоне и тем более почте. Да и ввод пришлось бы организовывать как то, если бы даже нашлись желающие. Но для продавца, только тогда можно не печатать чек на бумаге, если он знает телефон либо почту клиента. А это сокращает расходы предпринимателей как минимум на 30000 рублей за точку. Плюс кто то должен постоянно следить за этим принтером чеков, обслуживать, ремонтировать, заправлять бумагу, - это ещё не маленькие деньги за год набегают. Вот от этого гемора и было придумана железка и написано ПО. Причем по квитку от банка, эта сумма выводилась на дисплей контроллера и клиент мог использовать её на получение услуги. По сути дела, предприниматель имел бесплатный экваринг не привязанный ни к одному банку, и это был ещё один большой плюс. Не израсходованный баланс клиент мог забирать на карту клиента(по UID в базу данных). Таким образом всё работает в автомате. Извините модераторы, я здесь так подробно описал идею, в надежде, а вдруг здесь окажутся люди, приближенные к !!!!!! и доведут это до применения. Ведь все помнят, что с 1 июля 2021 года, закон (отложенный дважды) о применении кассовых аппаратов для всех окончательно вступает в силу. И после указанной даты принял деньги (не важно нал/безнал) обязан напечатать чек и передать его в ОФД. Да, и пока один не выданный чек штраф 10000 рублей. 10 чеков не распечатал, закрывай контору :). Вот так как то.
Заплатили бы ему больше, он бы понял, что вы состоятельный чел, что вам запросто может и десяток СМС-зачислений подряд прилететь. И сделал бы поддержку в ПО.
На самом деле, о моём бедственном положении исполнитель вряд ли мог точно знать. И запрошенный гонорар был уплачен в стопроцентном размере до начала работы. Если кому-то интересно, то исполнитель - это известный в местных кругах "специалист" Звягинцев/Литвиненко/DIYquest...
UPD: несколько смс очень любит присылать МЧС. Ну и другого спама можно ожидать
Звягинцев ещё на плаву? Где клиентуру набирает?
Я с ним имел год назад положительный опыт работы. Нашел через ВК
Приведите пример смс.
Приём в латинице 2 недели 3000 рублей.
В PDU формате по русски от 5000 рублей.
50% предоплата. Зависать точно не будет, но конечно при правильной сборке схемы.
Andycat2013@yandex.ru