Или как мы зажгли лампочку со смартфона через облачную службу на глазах изумленных студентов НГУ.

Полное техническое описание решения мы приводим внизу, а начнем с лирическо-философского пролога.

Глава 1. Лирическая


Практически все наши сотрудники получили высшее образование, и очень многие именно в Новосибирском государственном университете. Кто-то буквально недавно, кто-то – 10-20 лет назад, и все сталкивались с выбором будущей профессии. На последних курсах студентами мы выбирали кафедру, на которой проходили специализацию и защищали дипломы. И была такая замечательная традиция как Дни открытых дверей в институтах, лабораториях и компаниях, где сотрудники рассказывали, чем они занимаются, какие вопросы сейчас стоят перед наукой и технологиями и как можно в этом поучаствовать.

Что самое интересное в Днях открытых дверей для студента? Ходить, задавать вопросы, смотреть на реальных людей, которые занимаются настоящим делом, которое кому-то нужно.

По словам одного из наших сотрудников, для него, как для будущего специалиста, который никогда не видел практического применения своих знаний в рамках Дней открытых дверей, было очень интересно увидеть вживую тренажер стыковки для станции Мир, систему перехвата телефонных звонков, систему управления ТЭЦ, виртуальную студию, поговорить с людьми все это уже реализовавшими. И именно такие встречи помогли решить, где будет написан диплом и в какой из областей хотелось бы развиваться в профессиональном плане.

Сегодня Дни открытых дверей сменили Дни карьеры. Но нам хотелось сохранить дух этого мероприятия в своей презентации.

Мы поставили цель – сделать все согласно старым добрым и проверенным традициям с одной стороны, а с другой – показать студентам, что есть фундаментальные принципы, и мир достаточно сложная вещь, но это и хорошо. Это вызов и это возможность реализовать себя в профессиональном ИТ-обществе.

Именно с такими мыслями мы начали подготовку к Дням карьеры в НГУ – ведущей кузнице кадров среди Новосибирских вузов для любой уважающей себя ИТ-компании Новосибирска и многих других городов и стран.

Поэтому мы устроили стендовую сессию и мастер-класс, на который пришли руководители проектов и ведущие разработчики, участвующие в интересных боевых проектах для наших клиентов. Говоря просто – мы не ограничились девушками из HR, а выставили действующий «ИТ-спецназ» с шикарной темой.

Мы решили провязать несколько модных ИТ-тем и опыт из реального проекта:
  • Интернет вещей
  • Программирование микроконтроллеров
  • Облачные сервисы
  • Мобильные технологии

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

Но давайте по порядку.

Глава 2. Вводная. Философия интернета вещей


Если говорить в общем про интернет вещей, то мы бы выделили 2 направления в разработке решений.
  1. Удаленное управление “вещами”. Например, открытие/закрытие дверей, включение/выключение охранных систем или, в нашем случае, освещения.
  2. Сбор данных с удаленных датчиков, анализ этих данных, а также прогнозирование функционирования исследуемых систем, с возможным применением технологий машинного обучения.


Конечно, будущие решения класса IoT будут не выбирать одно из двух направлений, а сочетать их. Однако 2-й вариант кажется пока несколько сложным для проведения мастер-класса, т.е. написания его в online-режиме за полтора часа.

А вот что касается первого, то на основе опыта в разработке таких решений мы вполне смогли его продемонстрировать. Несколько упростив один из наших проектов, мы решили построить следующее.
  1. Есть настольная лампа. Лампа подключена к контроллеру, который периодически опрашивает сервис на предмет того, должна ли она гореть или нет.
  2. Есть сервис, который “живет” в AWS (Amazon Web Services). Сервис хранит в себе состояние “включена/выключена”, а также предоставляет API для получения или изменения этого состояния
  3. Есть мобильное приложение, которое позволяет управлять этим состоянием.

Ребята из .NET взяли на себя программирование микроконтроллера, парни из Java – облачную службу на Amazon, а наши «мобильные» коллеги – Android-приложение.

В презентации для студентов это звучало так:



Глава 3. Подготовительная. Несколько дней до дня Д.


Для демонстрации на стендовой сессии мы решили сделать отдельный девайс. Мы не поленились и сделали его классным в стимпанковском стиле – состарили деревянную коробку и нашли винтажные лампы.

Пара выходных и вечеров – и решение было готово, стильный девайс собран и работал.


Пара рабочих дней сверху и у нас готовы крутые дизайны плакатов, буклетов, стенда и футболок.


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




В течение трех прогонов мы научились укладываться в отведенный тайминг, отшлифовали код и текст и подготовили пару каверзных вопросов для студентов.

Глава 4. Зазывательная. День Д. Стендовая сессия


С утра мы одни из первых появились в НГУ, развернули стенд, убрали унылый стандартный стол, поставили нашу фирменную тумбу и на ней прямо в центре установили наш девайс. Он пользовался громадным успехом. Приходили смотреть и фотографировать все – студенты, преподаватели, фотографы, конкуренты и даже охранники. Наши буклеты и девайс сработали прекрасно – мы собрали полную аудиторию на следующий день!




Глава 5. Героическая. День Д+1. Мастер-класс.


И вот настал день мастер-класса. Мы приехали в НГУ и поняли, что, как не готовься, а в таких мероприятиях без затыков не обойдется.

Полная аудитория студентов, а у нас не подключется Mac к проектору, не пускает некоторые девайсы в универовский Wi-Fi, и даже амазоновские облака пытались встать в позу и не задеплоить наши сто раз проверенные сервисы. Но не зря мы выставили дрим-тим, все было разрешено «на лету», не выпадая из общего тайминга и структуры презентации.

Мы дали общую вводную про нашу компанию, интернет-вещей и как мы это будем зажигать лампочку. Затем по шагам прошли все стадии программирования комплексного решения, раздавая сувениры и брендированные кружки наиболее активным, умным и хитрым студентам. Хитрым, потому что некоторые из них попробовали нас хакнуть, и подход был довольно неплох, за что хакеры были награждены отдельно :).


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


А теперь к самому интересному для хабрачитателей – к коду.

Глава 6. Техническая


Итак, напоминаем, что наше решение должно состоять из 3-х компонентов.


  1. Микроконтроллер который включает/выключает лампочку. Этот микроконтроллер периодически запрашивает состояние лампочки у сервиса. Тут внимательный читатель может спросить, почему мы не использовали некие технологии, позволяющие реализовать Push со стороны сервера, и будет прав. В реальном проекте использовалось соединение с помощью WebSocket. Однако, чтобы уложиться в столь короткое время, мы решили максимально упростить систему.
  2. RESTfull Service, который «хостится» в AWS, а также тестовая страничка, которая позволяет им управлять.
  3. Мобильное приложение, которое также позволяет управлять состоянием лампочки.


6.1. Программируем микроконтроллер.


Сердцем нашего устройства является плата NodeMCU на базе контроллера ESP8266.


Из всего списка возможностей этой платы, нас интересуют поддержка беспроводных сетей Wi-Fi и GPIO — вводы/выводы общего назначения. Также, несмотря на то, что для этой платы нету ОС в привычном ее понимании, различные варианты прошивок поддерживают выполнение программ на языках C/C++, Lua, JavaScript и MicroPython.

Мы остановились на прошивке SMART.JS, программы для которой пишутся на языке JavaScript. Из возможностей этой прошивки будем использовать только http-клиент.



Нас интересует вывод номер 5 (GPIO5). Это цифровой вывод. Означает, что на выходе у него может быть логический “0” или логическая “1”. При логическом 0 реле будет выключено, при логической 1 – включено, и лампочка будет гореть.

Пререквизиты:
1. SMART.JS документация: docs.cesanta.com/smartjs/latest
2. SMART.JS прошивка: github.com/cesanta/smart.js
3. FNC (утилита для загрузки прошивок и программ на JavaScript): github.com/cesanta/fnc
4. Virtual COM port drivers: www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx
5. Тестовый сервис: тестовый сервис, который на GET запрос выдает JSON в формате:
{
     “resource_name”:  true/false
      …
}


Итак, к делу.

Для начала прошиваем на нашу плату прошивкой SMART.JS с помощью программы FNC. После этого у нас устройство начинает работать в режиме точки доступа и появляется сеть SMARTJS_???? (например, SMARTJS_FA352), пароль можно подсмотреть в консоли FNC.

Подключаемся к точке доступа и открываем адрес 192.168.4.1. У нас открывается конфигурационная страница, на которой мы вводим SSID и пароль для нашей сети. Сохраняем изменения, устройство перегружается, и мы готовы писать наше приложение.


Берем ваш любимый текстовый редактор и создаем файл app.js. Для начала выведем какое-нибудь приветственное сообщение в нашу консоль и определим вывод, к которому подключено реле и имя ресурса, ассоциированного с лампочкой:
console.log('device started.');
var pin = 5;
var resource = 'light01';


Инициализируем наш вывод и установим на выходе логический 0:
GPIO.setmode(pin, 0, 0);
GPIO.write(pin, false);

Установим callback-функцию на изменения состояния подключения:
Wifi.changed(changedFunc);

Функция принимает параметром числовой статус подключения. Пока просто выведем его на консоль вместе с текстовым представлением этого статуса:
function changedFunc(state) {
    console.log('Wifi state: ', state, Wifi.status());
}

Запустив приложение, мы видим, что статусу “got ip” соответствует код 2. Теперь давайте при успешном подключении к сети отправим запрос к сервису:
function changedFunc(state) {
    console.log('Wifi state: ', state, Wifi.status());
    if (state == 2) {
        mainFunc();
    }
}

function mainFunc() {
    Http.request({
        hostname: 'ngurestexample.us-east-1.elasticbeanstalk.com',
        port: 80,
        path: '/',
        method: 'GET'
    }, function (response){
        console.log(response.body);


    })
    .end()
    .setTimeout(5000, function(){
        console.log('timeout error');
    });
}

Нам приходит ответ в виде строки: {“light01”: false}. Преобразуем его в JS объект и устанавливаем состояние на нашем выводе в соответствии с тем, что получили из сервиса:
var states = JSON.parse(response.body);
GPIO.write(pin, !!states[resource]);

Ну, и чтобы наше устройство периодически опрашивало сервис, поставим повторный вызов mainFunc через setTimeout в функцию обработки ответа сервиса и в функцию обработки таймаута запроса:
setTimeout(mainFunc, 1000);

Теперь наше устройство готово к работе.

6.2. Служба в AWS



Elastic Beanstalk – это один из полезных сервисов AWS для быстрого развертывания и масштабирования веб-приложений. Его использование освобождает нас от необходимости самостоятельно создавать и настраивать окружение. Сервис на выбор предоставляет несколько заранее сконфигурированных. Все, что от нас потребуется, это выбрать подходящее окружение и загрузить собранное приложение, используя интуитивно понятный UI. Остальное сделает сервис Beanstalk. На выходе мы получим URL, по которому приложение будет доступно по HTTP.

Выберем окружение Tomcat (сервлет контейнер) и следующую конфигурацию:
  • операционную систему Amazon Linux;
  • отключим балансировщик нагрузки, т.к. он нам не понадобится;
  • выберем небольшую виртуальную машину t1.micro.


Эти же действия в картинках:










Кроме этого Beanstalk предоставляет возможность:
  • настраивать параметры сервера приложений (настройки JVM) и передавать переменные окружения;
  • подключать встроенные средства мониторинга CloudWatch;
  • выбрать подходящую базу данных или хранилище;

Перейдем к созданию нашего веб-приложения.

Цель – реализовать небольшое и простое приложение, которое бы могло хранить состояние лампочек (off/on) и изменять это состояние. Клиенты абсолютно разные (микроконтроллер и мобильное приложение), поэтому разумно использовать архитектуру REST.
Как итог наше приложение будет предоставлять следующее стандартное REST API:
  • [get] "/" – вернет состояние всех лампочек. Пример: { «лампочка-1»: false, “лампочка-2": true }
  • [get] "/{resource}" – вернёт состояние запрашиваемой лампочки
  • [delete] "/{resource}" – удалит лампочку из списка лампочек
  • [put] "/{resource}" – обновит состояние заданной лампочки
  • [post] "/{resource}" – создаст новую лампочку

Писать код мы будем на Java, собирать результаты нашей работы с помощью Maven’а, а для написания кода используем библиотеку resteasy.

С помощью Maven подключим необходимые зависимости
[ github.com/EBTRussia/nsucareerdays2016/edit/master/cloud/sample-web-app-rest]easy/pom.xml ]:
resteasy-jaxrs – для работы с jaxrs
resteasy-servlet-initializer – для интеграции с томкатом
resteasy-jackson2-provider – для работы с json

Почему resteasy. В мире Java существует много инструментов, которые позволяют создавать rest-приложения (Jersey, Spring, Spark, и т.д.). Мы просто выбрали один из них, который, к слову, входит в стандартную поставку сервера приложений WildFly.

[ github.com/EBTRussia/nsucareerdays2016/blob/master/cloud/sample-web-app-resteasy/src/main/java/ru/ebt/LightAppController.java ]
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public class LightAppController {
	private ConcurrentMap<String, Boolean> resource = new ConcurrentHashMap<>();

	@GET
	public Map getAll() {
   	return resource;
	}

	@GET
	@Path("/{resource}")
	public Boolean get(@PathParam("resource") String r) {
   	return resource.get(r);
	}

	@PUT
	@Path("/{resource}")
	public Boolean put(@PathParam("resource") String r, Boolean status) {
   	if (resource.containsKey(r)) {
       		resource.put(r, status);
       		return status;
   	}
   	throw new WebApplicationException(Response.Status.NOT_FOUND);
	}

	@POST
	@Path("/{resource}")
	public Boolean post(@PathParam("resource") String r, Boolean status) {
   		resource.put(r, status);
   		return status;
	}

	@DELETE
	@Path("/{resource}")
	public void delete(@PathParam("resource") String r) {
   		resource.remove(r);
	}
}

GET, PUT, POST, DELETE – Анотации из JAX-RS, которые показывают, какими http методами обращаться к нашиму api.

Path("/{resource}") & @PathParam(«resource») показывают, по какому URL обращаться к api и какую часть URL мы хотим обрабатывать как параметр в логике приложения. В нашем случае, resource — имя/id для лампочки.

Для хранения состояния наших ламп мы используем ConcurrentHashMap [ docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html ], потокобезопасный словарь ключей и значений.

Теперь превратим наш обычный класс в настоящий rest-сервис. Для этого создадим конфигурационный класс BaseApplication, который унаследуем от javax.ws.rs.core.Application. Внутри метода getSingletons() перечислим все классы, которые будут REST сервисами.
@ApplicationPath("")
public class BaseApplication extends Application {
	@Override
	public Set<Object> getSingletons() {
   	HashSet<Object> objects = new HashSet<>();
   	objects.add(new LightAppController());
   	return objects;
	}
}


Собираем приложение. Идём в рутовую директорию нашего приложения и выполняем команду:
mvn clean install

После идём в созданную maven’ом папку target и забераем *.war файл, деплоим его на томкат с помощью сервиса BeansTalk.

Просто нажмём кнопку, всё должно взлететь:


Проверяем, что всё работает:
  1. дергаем URL нашего приложения методом get [http://какойто.адрес/ ] и в ответ получим пустой json: {}
  2. с помощью любого REST клиента выполняем запрос методом POST [http://какойто.адрес/light01 ] в тело запроса пишем true
  3. и видим, что лампочка загорелась) (можно ещё раз дёрнуть get “/” и в ответ получим {“light01”: true})


6.3. Android-приложение





Шаг 0. Подготовительный
Для создания Android-приложений используется система автоматической сборки Gradle. В его скрипте build.gradle мы подключим несколько зависимостей, которые упростят нам и написание кода, и жизнь:
dependencies {
   compile 'com.jakewharton:butterknife:7.0.1'
   compile 'com.squareup.retrofit2:retrofit:2.0.0'
   compile 'com.squareup.retrofit2:converter-gson:2.0.0'
}

Библиотека Butterknife поможет нам проще настраивать графический интерфейс, а Retrofit идеально подходит в качестве HTTP клиента, если вы планируете взаимодействовать с REST-сервисом.

Шаг 1. Графический интерфейс
На пустой экран (activity) добавим компонент Switch, который как никто другой хорошо подходит для управления лампочкой, почти как настоящий выключатель:
<Switch
       android:id="@+id/light_switch"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="Лампочка"/>

Мы дали нашему компоненту уникальное имя light_switch и написали текст, который будет виден пользователю.

Теперь добавим переключатель в код нашей activity:
public class MainActivity extends AppCompatActivity {

   @Bind(R.id.light_switch) SwitchCompat lightSwitch;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       ButterKnife.bind(this);
   }

   @OnClick(R.id.light_switch)
   void onLightSwitchClicked(Switch lightSwitch) {
       boolean checked = lightSwitch.isChecked();
       Toast.makeText(this, "Switch checked = " + checked, Toast.LENGTH_SHORT).show();
   }

}


Мы воспользовались двумя аннотациями из библиотеки ButterKnife: Bind и OnClick. Первая связывает наш переключатель, объявленный в xml-разметке с тем переключателем, что объявлен в коде. Второй устанавливает метод onLightSwitchClicked() в качестве обработчика клика по нашему переключателю.

Шаг 2. HTTP-клиент
Создать http-клиент совсем не сложно, если прибегнуть к помощи библиотеки retrofit. Нужно лишь создать интерфейс и описать в нём все запросы к серверу в качестве его методов, после чего скормить этот интерфейс в retrofit, который самостоятельно создаст подходящую реализацию нашего интерфейса.
public interface WebApi {

   @GET("/")
   Call<Map<String, Boolean>> list();

   @POST("/{resource}")
   Call<Boolean> switchBulb(@Path("resource") String resource, @Body Boolean enabled);
}

В нашем интерфейсе всего 2 метода:
  • list() — GET запрос для получения всех лампочек и их состояний в виде словаря <String, Boolean>
  • switchBulb(...) — POST запрос, создающий (или пересоздающий) состояние лампочки:
    webApi = new Retrofit.Builder()
                   .baseUrl(getString(R.string.api_url))
                   .addConverterFactory(GsonConverterFactory.create())
                   .build()
                   .create(WebApi.class);
    


Здесь мы указываем библиотеке retrofit свой базовый url, сообщаем, что запросы и ответы будут в формате JSON и указываем только что написанный интерфейс, после чего HTTP-клиент уже готов к работе.

Шаг 3. Дружим UI и HTTP-клиент
Во-первых, нужно получить и отобразить актуальное состояние лампочки. Сделаем GET-запрос и поищем в вернувшемся словаре лампочку с именем “light01”:
webApi.list().enqueue(new Callback<Map<String, Boolean>>() {
           @Override
           public void onResponse(Call<Map<String, Boolean>> call, Response<Map<String, Boolean>> response) {
               Boolean light01Enabled = response.body().get("light01");
               lightSwitch.setChecked(Boolean.TRUE == light01Enabled);
           }

           @Override
           public void onFailure(Call<Map<String, Boolean>> call, Throwable t) {

           }
       });

Во-вторых, при переключении лампочки на клиенте нужно уведомлять об этом сервер. Мы уже написали обработчик клика по переключателю на предыдущем шаге, теперь добавим в него выполнение http-запроса:
@OnClick(R.id.light_switch)
   void onLightSwitchClicked(Switch lightSwitch){
       boolean checked = lightSwitch.isChecked();
       webApi.switchBulb("light01", checked).enqueue(new Callback<Boolean>() {
           @Override
           public void onResponse(Call<Boolean> call, Response<Boolean> response) {
               Toast.makeText(MainActivity.this, "Light01 changed", Toast.LENGTH_SHORT).show();
           }

           @Override
           public void onFailure(Call<Boolean> call, Throwable t) {

           }
       });
   }



И-и-и, лампочка гори!


Глава 7. Короткая, заключительная.



C полным кодом решения можно ознакомиться по ссылке: github.com/EBTRussia/nsucareerdays2016

Мастер-классом и этим примером мы хотели показать – классные и интересные вещи можно делать за короткое время и с минимумом усилий. Нужна идея. Дерзайте! Именно из простых и нужных вещей рождаются целые отрасли, такие, как интернет вещей.

И приходите к нам работать :) У нас действительно уникальный коллектив и очень интересные проекты.
До встречи!

Комментарии (21)


  1. den1s1
    08.04.2016 17:15
    +6

    Конечно, по сравнению с программистами микроконтроллеров, айтишники иначе понимают «программирование микроконтроллеров»

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


    1. eastbanctech
      09.04.2016 14:54

      Действительно термин микроконтроллер тут не совсем точен, но мы специально его ипользуем, чтобы не путать, с терминами «контроллер», который ипользуется в Java части, и «устройство» которым мы называем всю плату.
      А что касается скриптовых языков, нам кажется, что ключ к распространению подобного рода решений это дешевые «микроконтроллеры» :) вроде NudeMCU, и простые и популярные языки, такие как JavaScript.


      1. den1s1
        09.04.2016 15:08
        +1

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

        не удержусь и перескажу один мой разговор с представителем очень крупной айти компании:
        я: мне нужно реализовать на микроконтроллере протокол Х
        он: на твоем микроконтроллере будет установлена Windows 10?
        я: нет, ему не хватит «вычислительной мощности» для этого
        он: а зачем ты занимаешься ерундой, сейчас же есть RPi за несчастных $35 и очень небольшого размера — используй его в качестве микроконтроллера

        сейчас с этими подходами дальше игрушек аля самодельный умный дом уйти не получится


  1. loginsin
    08.04.2016 17:40
    +8

    А я вчера развел в sprlayout плату, распечатал, проверил еще раз на бумажке, распечатал уже на плату, вытравил, облудил, запаял. Ушло примерно часа 4. С замиранием сердца подключил ft232, подал внешнее питание и… виндовс сказала, что все usb устройства вдруг выключились, цифровой индикатор весело моргнул и потух навсегда. За ним отправились в вечность все транзюки и сам мк. Проверил еще раз: перепутал полярность на мк! Срезал дорожки, напаял пару проволочек (я еще не знал, что сгорела вся рассыпуха на плате) и… снова ничего. В 7 часов утра понял, что перепаивать надо вообще все (разводить по новой буду, когда найду все косяки, если они еще есть) и пошел спать. Романтика…

    PS: К счастью, на мамках современных стоит защита, которая при КЗ вырубает мост. Перезагрузка вернула юсб к жизни.


    1. av0000
      08.04.2016 18:38
      +1

      +1
      … Вот почему я уже лет 5 как пользуюсь diptrace-ом. Хоть из-под wine, зато привязка схемы к плате. Правда, уже второй заказ от китайцев режу и допаиваю поверх — «ибо — мысль!» © о программистах и админах. Пока готовые платы приедут, или косяк в схеме найдёшь, или дополнение какое придумаешь…


      1. kx13
        11.04.2016 15:35

        По моему, для простых схем KiCad тоже неплохо подходит.
        И в Linux работает без проблем и многих ошибок позволяет избежать.


        1. av0000
          11.04.2016 17:17

          Честно в очередной раз попробовал (с пару месяцев назад), увы, опять поплевался и вернулся к диптрейсу.

          Схему нарисовать, без привязки к компонентам — весьма, проверить электрику — уже возникают вопросы (почему я на каждую шину должен лепить fake power bus, чтобы на меня не ругались за кривую схематику?), А как начинаешь разводить — беда :(

          Самый главный минус для меня — слишком примитивная работа с платой — стоит сдвинуть компонент, все дорожки к нему надо трассировать заново. Причём, народ про это дело шумит на форумах давно — «типа, единственная софтина, кто не сделал перемещение трассированных элементов».

          На cubietruck-е поставил, думал обойтись совсем без ноута. Повозился с месяц редкими подходами, не пошло.


  1. LeonidZ
    08.04.2016 19:01

    Автору статьи огромная просьба хотя бы 1 раз прочитать ее (а статья реально хорошая, интересная), и подправить грамматические ошибки (их очень много, правда, а ведь вроде как «Практически все наши сотрудники получили высшее образование...»).


    1. eastbanctech
      09.04.2016 14:54

      исправились


      1. LeonidZ
        09.04.2016 16:27

        Благодарю! Гораздо приятнее )


  1. spmbt
    08.04.2016 19:03
    +4

    AWS — правильной дорогой идёте, как в https://habrahabr.ru/post/276539/. Но получилось ли у вас 8 машин и 12 сервисов?


  1. lopatoid
    08.04.2016 19:52
    -4

    За 1.5 часа таким методом можно сделать, только если всё заранее подготовить. Ну, хотя бы Android Studio скачать и поставить. За настоящие 1.5 часа с нуля (то есть на компьютере, на котором абсолютно ничего нет, даже драйверов на CP210x) у меня получилось такое сделать с blynk.
    http://www.blynk.cc/
    При этом esp8266 и сам Blynk я использовал в первый раз.


    1. fshp
      11.04.2016 01:46
      +1

      За настоящие 1.5 часа с нуля

      Вы лишь ведро песка накопаете для будущего кристалла кремния...


  1. terryP
    09.04.2016 03:31
    +3

    то есть на компьютере, на котором абсолютно ничего нет

    Ни биоса, ни ОС? Все сами всё с нуля написали за 1.5 часа?

    ИМХО, это какое-то очень специальная олимипада соревноваться кто быстрее напишет на компе на котором вообще ничего нет. Какой в этом смысл? Можно, конечно, говорить что ты крут потому что можешь в блокноте написать программу в машинных кодах на память, без компиляторов, IDE и инета. Но ЗАЧЕМ? Зачем программировать на компе где ничего нет даже средств разработки? Просто потому что?


  1. xBrowser
    09.04.2016 12:19
    +1

    Без этого

    видео


  1. midgard2014
    09.04.2016 14:43
    +3

    Столько написали, а полезного 0!
    Пахнет маркетингом!


    1. eastbanctech
      10.04.2016 12:37

      Статья писалась для людей без опыта разработки IoT решений. Более продвинутые читатели, конечно, не найдут здесь для себя нового.


  1. lzb_j77
    09.04.2016 14:43
    +5

    (голосом Скорохода) — Я извиняюсь!

    Чтоб зажечь лампочку через радиоканал нужно привлекать СТОЛЬКО ресурсов и различной инфраструктуры? Я не могу поверить, что сегодня это делается такими методами, с привлечением облаков. Такие поделки только вредят обучению — у студентов не появляется понимания, зачем нужны микроконтроллеры и для чего они предназначаются.

    это всё вызвало у меня внутренний протест — столько лишних байтов! (с) SerzhSoft


    1. eastbanctech
      10.04.2016 12:36

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


      1. lzb_j77
        10.04.2016 15:49

        Да, конечно — задач — великое множество. Да, детей надо учить решать самые разные задачи. Это очень здОрово, что вы учите детей, честное слово.
        А поймут ли они при этом, что такое микроконтроллер, зачем он нужен и какое его предназначение?
        Разве что их завлекают на обучение в НГУ и уж там то показывают и объясняют, что такое мироконтроллер :)

        p.s. наблюдая за студентами в своём небольшом городе, я с удивлением обнаружил — им лень пройти 2-3 остановки пешком, они едут на маршрутках. Просто лень.


  1. Iceg
    09.04.2016 23:52

    Если говорить в общем про интернет вещей, то мы бы выделили 2 направления в разработке решений.

    Удаленное управление “вещами”. Например, открытие/закрытие дверей, включение/выключение охранных систем или, в нашем случае, освещения.
    Сбор данных с удаленных датчиков, анализ этих данных, а также прогнозирование функционирования исследуемых систем, с возможным применением технологий машинного обучения.

    С т.з. классической теории автоматизированного управления это две части одного целого. Вы не думали, что управлять лампочкой, не зная её настоящего состояния, хм, непродуктивно?) Поэтому как-то странно разделять сбор данных и управление. Да ещё и ставить управление на первое место.