Нужно отладить код. Прием СМС с парсингом суммы.

klbng
Offline
Зарегистрирован: 11.05.2021

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

Идея такова: СМС от сбербанка приходит на sim800l, нужно из текста СМС вытянуть сумму зачисления.
Сейчас код работает, но нестабильно. Если прислать несколько СМС подряд - вообще виснет. Есть мнение, что это из-за использования стрингов.

Вот кусок кода именно с приемом СМС.

#include <SoftwareSerial.h>

SoftwareSerial gsm(8, 9); // RX, TX

unsigned long tm = 0, cur = 0;
bool flag = 0, reg = 1;
String msg = "";

void setup () {
  Serial.begin(9600);
  gsm.begin(19200);
  gsm.flush();
  gsm.println("at+cmgf=1;&W");delay(100);
  gsm.println("at+cscs=\"gsm\";&W");delay(100);
}

void loop () {
  if (reg) {
    reg = 0;
    gsm.println("at+cmgl=\"rec unread\"");
    delay(10);
  }
  if (gsm.available()) {
    char inChar = gsm.read();
    //Serial.write(inChar);
    msg += inChar;
    /*tm = millis();
    msg = "";
    do {
      cur = millis();
      if (gsm.available()) {
        char inChar = gsm.read();
        msg += inChar;
      }
      /*Serial.print(" ");
      Serial.print(inChar, HEX);
      Serial.print(" ");*/
    tm = millis();
    flag = 1;
  }
  if (flag && millis() - tm >= 7000) {
    flag = 0;
    msg.toLowerCase();
    //Serial.println("MSG:" + msg);
    
    if (msg.indexOf("+cmti: \"sm\"") != -1 || msg.indexOf("+cmti: \"me\"") != -1) {
      gsm.println("at+cmgl=\"rec unread\"");
      delay(10);
    }
    if (msg.indexOf("at+cmgl=\"rec unread\"") != -1) {
      String line = "";
      byte row = 0;
      for (int i = 0; i < msg.length(); i++) {
        line += msg[i];
        if (msg[i] == '\n') {
          //Serial.println("row:" + String(row) + " str=" + line);
          row++;
          if (reg) {
            reg = 0;
            Serial.println(UCS2ToString(line));
            String money = UCS2ToString(line);
            if (money.indexOf("аеревад ") != -1) {
              money = money.substring(money.indexOf("аеревад ") + 14, money.indexOf("р Б"));
              //Serial.println("money:" + money);
            } else if (money.indexOf("зачисаеаие ") != -1) {
              money = money.substring(money.indexOf("зачисаеаие ") + 20, money.indexOf("р Б"));
              //Serial.println("money:" + money);
           }
            Serial.println("money:" + String(money.toInt()));
            gsm.println("at+cmgda=\"del read\"");
          }
          if (line.indexOf("+cmgl:") != -1) {
            reg = 1;
          }
          line = "";
        }
      }
    }
    
    msg = "";
  }
  if (Serial.available()) {
    //while (Serial.available() > 0) 
    gsm.write(Serial.read());
  }
}

String UCS2ToString(String s) {                       // Функция декодирования UCS2 строки
  String result = "";
  unsigned char c[5] = "";                            // Массив для хранения результата
  for (int i = 0; i < s.length() - 3; i += 4) {       // Перебираем по 4 символа кодировки
    unsigned long code = (((unsigned int)HexSymbolToChar(s[i])) << 12) +    // Получаем UNICODE-код символа из HEX представления
                         (((unsigned int)HexSymbolToChar(s[i + 1])) << 8) +
                         (((unsigned int)HexSymbolToChar(s[i + 2])) << 4) +
                         ((unsigned int)HexSymbolToChar(s[i + 3]));
    if (code <= 0x7F) {                               // Теперь в соответствии с количеством байт формируем символ
      c[0] = (char)code;
      c[1] = 0;                                       // Не забываем про завершающий ноль
    } else if (code <= 0x7FF) {
      c[0] = (char)(0xC0 | (code >> 6));
      c[1] = (char)(0x80 | (code & 0x3F));
      c[2] = 0;
    } else if (code <= 0xFFFF) {
      c[0] = (char)(0xE0 | (code >> 12));
      c[1] = (char)(0x80 | ((code >> 6) & 0x3F));
      c[2] = (char)(0x80 | (code & 0x3F));
      c[3] = 0;
    } else if (code <= 0x1FFFFF) {
      c[0] = (char)(0xE0 | (code >> 18));
      c[1] = (char)(0xE0 | ((code >> 12) & 0x3F));
      c[2] = (char)(0x80 | ((code >> 6) & 0x3F));
      c[3] = (char)(0x80 | (code & 0x3F));
      c[4] = 0;
    }
    result += String((char*)c);                       // Добавляем полученный символ к результату
  }
  return (result);
}

unsigned char HexSymbolToChar(char c) {
  if      ((c >= 0x30) && (c <= 0x39)) return (c - 0x30);
  else if ((c >= 'A') && (c <= 'F'))   return (c - 'A' + 10);
  else                                 return (0);
}

 

Ищу исполнителя, готового довести до ума этот проект

man9913
Offline
Зарегистрирован: 19.03.2016

напишу заново корректно работающий скетч. 2000р, предоплата 50%, man9913@mail.ru

SAB
Онлайн
Зарегистрирован: 27.12.2016

Где то год назад, пытались договориться со сбером, присылать в обратном квитке при оплате через телефон не имя отчество и букву фамилии, а номер телефона с которого был осуществлен перевод суммы. Получили отказ. Хотя всё ПО уже было написано под 590 модем. А идея была классная - автоматизация оплаты услуги, с пробитием (фискализацией) чека на конкретного человека и отсылки ему на телефон QRcoda или SMS от ОФД. Так жаль потраченных ресурсов. Это действие со стороны сбера даже не попадало под 157-ФЗ, сначала вроде согласились подумать, но потом, наверно, сказали себе, что нам и так не плохо живется, зачем делать какие то телодвижения. И очередной раз плюнули на просьбу  общественности. Ур-ы.

klbng
Offline
Зарегистрирован: 11.05.2021

SAB пишет:

Где то год назад, пытались договориться со сбером, присылать в обратном квитке при оплате через телефон не имя отчество и букву фамилии, а номер телефона с которого был осуществлен перевод суммы. Получили отказ. Хотя всё ПО уже было написано под 590 модем. А идея была классная - автоматизация оплаты услуги, с пробитием (фискализацией) чека на конкретного человека и отсылки ему на телефон QRcoda или SMS от ОФД. Так жаль потраченных ресурсов. Это действие со стороны сбера даже не попадало под 157-ФЗ, сначала вроде согласились подумать, но потом, наверно, сказали себе, что нам и так не плохо живется, зачем делать какие то телодвижения. И очередной раз плюнули на просьбу  общественности. Ур-ы.

Уговаривал их слать СМС на транслите (типа старый телефон у меня) - не хотят. А фискализация мне не нужна ("уплачиваю" НПД).
Есть лайфхак - нужно к сберкарте привязать два номера телефона. При переводе на номер "1", на него приходит полный текст с отправителем и т.д. Номер "2" получает только СМС "зачисление 100500 рублей". Так для работы достаточно оперировать только с одним типом сообщений.

SAB
Онлайн
Зарегистрирован: 27.12.2016

Да хоть 10 номеров привязывай к карте. Для того, чтобы не печатать чек на бумажном носителе, ты должен этот чек привязать к конкретному клиенту (даже полное ФИО не катит). И при передаче чека к ОФД предоставить либо номер телефона данного человека, либо адрес его электронной почты. Никто, естественно, из клиентов не будет предоставлять таких данных о своём телефоне и тем более почте. Да и ввод пришлось бы организовывать как то, если бы даже нашлись желающие. Но для продавца, только тогда можно не печатать чек на бумаге, если он знает телефон либо почту клиента. А это сокращает расходы предпринимателей как минимум на 30000 рублей за точку. Плюс кто то должен постоянно следить за этим принтером чеков, обслуживать, ремонтировать, заправлять бумагу, - это ещё не маленькие деньги за год набегают. Вот от этого гемора и было придумана железка и написано ПО. Причем по квитку от банка, эта сумма выводилась на дисплей контроллера и клиент мог использовать её на получение услуги. По сути дела, предприниматель имел бесплатный экваринг не привязанный ни к одному банку, и это был ещё один большой плюс. Не израсходованный баланс клиент мог забирать на карту клиента(по UID в базу данных). Таким образом всё работает в автомате. Извините модераторы,  я здесь так подробно описал идею, в надежде, а вдруг здесь окажутся люди, приближенные к !!!!!! и доведут это до применения. Ведь все помнят, что с 1 июля 2021 года, закон (отложенный дважды) о применении кассовых аппаратов для всех окончательно вступает в силу. И после указанной даты принял деньги (не важно нал/безнал) обязан напечатать чек и передать его в ОФД. Да, и пока один не выданный чек штраф 10000 рублей. 10 чеков не распечатал, закрывай контору :). Вот так как то.

klbng
Offline
Зарегистрирован: 11.05.2021

rst пишет:

klbng пишет:
Если прислать несколько СМС подряд - вообще виснет. Есть мнение, что это из-за использования стрингов.
Я конечно не знаю что там в нижнем белье носил слившийся исполнитель - стринги или что-то ещё. Но думаю, что он, исходя из малости уплаченного вами ему гонорара, определил что вы - человек небогатый и поэтому вам в принципе не может приходить более одной подряд СМС-ки с суммами зачисления из банка.

Заплатили бы ему больше, он бы понял, что вы состоятельный чел, что вам запросто может и десяток СМС-зачислений подряд прилететь. И сделал бы поддержку в ПО.

На самом деле, о моём бедственном положении исполнитель вряд ли мог точно знать. И запрошенный гонорар был уплачен в стопроцентном размере до начала работы. Если кому-то интересно, то исполнитель - это известный в местных кругах "специалист" Звягинцев/Литвиненко/DIYquest...

UPD: несколько смс очень любит присылать МЧС. Ну и другого спама можно ожидать

sadman41
Offline
Зарегистрирован: 19.10.2016

Звягинцев ещё на плаву? Где клиентуру набирает?

klbng
Offline
Зарегистрирован: 11.05.2021

Я с ним имел год назад положительный опыт работы. Нашел через ВК

andycat
andycat аватар
Онлайн
Зарегистрирован: 07.09.2017

Приведите пример смс.
Приём в латинице 2 недели 3000 рублей.
В PDU формате по русски от 5000 рублей.
50% предоплата. Зависать точно не будет, но конечно при правильной сборке схемы.
Andycat2013@yandex.ru