Як ми розсилали SMS зі старої Nokia і телефон на Android

image

Приблизно рік тому ми запустили свій маленький проект з оповіщеннями про поломки Москвовського метро.

Найголовнішою проблемою у ньому виявилася розсилка смс. Ми не очікували, що проект сподобається і у нас буде 1500+ реєстрацій. У самому кращому випадку ми розраховували на 300. Цим ми були приємно здивовані.

Проблема з смс в першу чергу із-за ціни. Одна розсилка виходила приблизно 3000 рублів. З урахуванням того, що ціна 1 смс 1,5 рубля. Були часи, коли неполадки у рухом поїздів були кожні 3 дні, тобто 10 поломок в місяць. 3000*10 = 30 000 рублів. Дорогувато для проекту, який не фінансується.

Тут ми почали винаходити велосипед. А саме, шукати тарифи з дійсно безлімітними смс. У підсумку ми його знайшли. Варто було щось близько 600 рублів на місяць. Далі потрібно було вирішити питання з відправкою смс. І тут настав час стародавньої nokia 6610i, яка припадала пилом у шафі, як пам'ять про минулі епохи. Але її довелося трохи доопрацювати, а саме підключити по uart до ноута, щоб відправляти завдання.

imageСхема

Пари діодів тут потрібна щоб скинути напругу з 5V до ~3.4 V. Падіння на діодах сумарно виходить 1.6 V при струму 1А. Такий струм нокія споживає тільки при активній роботі з мережею, а більшу частину часу падіння на них буде близько 1.5 V.
Великий і товстий конденсатор потрібен щоб згладжувати споживання телефону в той момент коли працює передавач, і він багато жере.
А резистори — замінюють терморезистор та пін ідентифікації батарейки (BSI), за яким nokia розуміє що до неї підключено акумулятор.
У нас відповідних номіналів резисторів не знайшлося, тому зібрали з того що було.

image

Для відправки використовувалася програма gnokii, з назви якої цілком очевидно, що писалася вона як раз для таких цілей.

Конфіг від нашої 6610i:

[global] port = /dev/ttyUSB0
connection = dlr3p
model = 6510


Команда для відправки
echo 'text' | gnokii --sendsms number


Щоб розсилати можна було не тільки від root, потрібно виставити відповідні права на /dev/ttyUSB0

Тут сподобалося, що нам могли відповідати, і нам відповідали. Але і проблеми тут не закінчилися, а саме швидкість: така розсилка займала 4 години. Тому таким чином ми розсилали інформацію, яка актуальна тривалий період, наприклад, про закриття частини лінії на ремонт. 1 сімки нам вистачало приблизно на 3 тисячі повідомлень, тобто на пару розсилок. Далі нас блокували. Ми дзвонили в ТП і запитували причини блокування, на що нам відповіли — розсилка. Один раз нам вистачило однієї сімки на 5 розсилок, таймаут робили побільше і змінювали текст. І нам завжди щастило на гарні номери — дрібниця, але приємно.

А оскільки в звичайному випадку у нас актуальність інформації становить 40 хвилин, розсилка в ідеалі повинна бути за пару хвилин. Тому ми вирішили зробити розсилку на телефоні Android. Головною перевагою цього рішення була швидкість, правда теж далеко не ідеально. 1 смс відправлялася за 1.5 секунди, що в результаті виходило приблизно в 37 хвилин. Далі можна було параллелить за допомогою підключення ще телефону і добитися потрібної швидкості. Але тут нас задушив оператор, який блочил нас або посредь першої розсилки або на початку другої.

Логіка програми уклалася в періодичному отриманні завдання з сервера. Приблизно раз у кілька хвилин додаток зверталася на сервер за командою в форматі json, яка складалася з масиву телефонних номерів і текстів смс.

У нас був потік для забору команди з таймаутом, потік для розсилки смс, BrodasReceiver для запуску після завантаження. Але проект загубився, зважаючи давності, тому повного коду не буде. Текст смс ми урізали до максимуму 1 смс — 70 символів (це для кирилиці), це робила серверна частина, але на всяк випадок відправка смс була рівно на 70 символів:

SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage("NUM", null, "TXT", null, null);


не забуваючи про права на відправку смс на маніфест

<uses-permission android:name="android.permission.SEND_SMS" />


Для автозапуску після включення не забуваємо про права:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />


Прописати в маніфест:

<receiver android:name=".Boot"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>


Код Boot:

public class Boot extends BroadcastReceiver 
{

@Override
public void onReceive(Context context, Intent intent)
{
тут запуск потоку
}
}


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

Ну і в Activity додаємо запуск потоку.

Так само дозволяємо додатком доступ в інтернет:

<uses-permission android:name=«android.permission.INTERNET»/>

І ще важливий момент, щоб наше додаток працювало навіть з вимкненим дисплеєм потрібно вызвывать PowerManager. Інакше система буде присипляти додаток за своїм бажанням, для економії заряду, і запити будуть виконуватися нерегулярно.

Для цього додаємо пермишн:

<uses-permission android:name="android.permission.WAKE_LOCK" /> 


Дабавляем код Activity:

PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP|
PowerManager.FULL_WAKE_LOCK| PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "");


І в потік
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();

Звернення до сервера, обробка отриманого json 

wl.release();


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

Далі ми пробували розсилати через Whatsapp, але тут номери вмирали кожні 10 повідомлень, а то і швидше. А реєстрація 1 номери коштувала 7 рублів. Ми знову почали виходити на ті самі цифри, з яких почали.

А не так давно ми зробили бота для телеграм — https://telegram.me/msk_metro, тут все так само як і з PushBullet, який ми підключили на прохання після першого поста на хабре. Тільки тут ми можемо видаляти випадково пройшли модерацію повідомлення, а в PushBullet — ні.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.