Relay and ESP8266 – part 2: mobile app

Lets create a mobile app to control our relay. To develop multiplatform application we will use Xamarin. Why? Because I have no idea how it works and I want to try 🙂

Our software must support 4 actions, toggling on and off both channels. To make layout as simple as possible lets stick with four buttons. I used xaml to create UI, it is a file which describe layout and widgets. I’m not sure what is better: write UI in code or use xaml.

Pressing one button will broadcast a JSON message with our event.

Xamarin has few types of application. Today Forms Portable is my choice for project.

I wont digg into installing Visual Studio and Xamarin or setting phone to developer mode. It is easy to find on the net.

Xamarin – prepare project

We will go with Xamarin.Forms portable with xaml support. Read about differences . Why such choice? I read that portable is better and I hope xaml will allow us to quickly create interface.

Start new project and select Templates / Visual C# / Cross-Platform. From right side select Blank Xaml App (portable), enter some nice name like LightSwitch and press OK.

This will crate a skeleton for project with few platforms. My target platform is Android and Windows 10 Mobile (UWP) so I removed rest.

Now do a test deploy, in my case it was for android device. But I couldn’t do it! I had to update Xamarin.Forms! But I discovered this after googling – not a good start 😦
After update app deployed successfully.

Xamarin – UI

Layout is described in xaml file. I used it because I thought I could use a graphical creator but no! I have to edit file manually – now I ‘m sure that without xaml is much better. But lets stick to it for some time more.

We have a two relays so we need four buttons. Two on each channel. I prefer those buttons and not some switches because we have no way of checking relay state (for now:P). Main template is in MainPage.xaml file. Add required widgets:

<StackLayout>
    <Label Text="Channel 1" VerticalOptions="Center" HorizontalOptions="Center" x:Name = "Label1"/>
    <StackLayout Orientation="Horizontal" HorizontalOptions="Center">
      <Button Text="Enable" />
      <Button Text="Disable" />
    </StackLayout>
    <Label Text="Channel 2" VerticalOptions="Center" HorizontalOptions="Center" />
    <StackLayout Orientation="Horizontal" HorizontalOptions="Center">
      <Button Text="Enable" />
      <Button Text="Disable" />
    </StackLayout>
  </StackLayout>

This give us such layout:

Android

Android

wp_layout

Windows 10 Mobile

Rather simple but yey! It is something !

Hook events to buttons

Our buttons do nothing but it will change now. Only difference between them is an event name to send.
Create functions that we will later attach to buttons (file MainPage.xaml.cs):

        private void OnChannel1EnableClick(object sender, EventArgs args)
        {
            this.sendMessage("channel1.on");
        }

        private void OnChannel2EnableClick(object sender, EventArgs args)
        {
            this.sendMessage("channel2.on");
        }

        private void OnChannel1DisableClick(object sender, EventArgs args)
        {
            this.sendMessage("channel1.off");
        }

        private void OnChannel2DisableClick(object sender, EventArgs args)
        {
            this.sendMessage("channel2.off");
        }

Create one stub function. It will create JSON message and broadcast it:

        private void sendMessage(string action)
        {
          
        }

Go back to xaml and attach those functions:

      <Button Text="Enable" Clicked="OnChannel1EnableClick" />
      <Button Text="Disable" Clicked="OnChannel1DisableClick"/>


      <Button Text="Enable" Clicked="OnChannel2EnableClick"/>
      <Button Text="Disable" Clicked="OnChannel2DisableClick"/> 

Code compiled and deployed without problems. Good!

Broadcast

This was a surprise. In C# you have a UdpClient from System.Net.Sockets; but not in Xamarin! This is bad… But there is a nice library for this: (https://github.com/rdavisau/sockets-for-pcl) and this is good 🙂
We may now add some code to sendMessage function:

private void sendMessage(string action)
{
    UdpSocketClient client = new UdpSocketClient();
    var msgBytes = Encoding.UTF8.GetBytes(action);
    client.SendToAsync(msgBytes, "192.168.1.255", PORT);
}

Define PORT at the top of class as const:

const int PORT = 5053;

But we broadcast a string and we want a JSON! Ok, can do it.

JSON message

Lets create a class for our message. It will have all fields, default values and it can be serialized to JSON. All good.

Create new class Protocol.


namespace LightSwitch
{
class Protocol
{
public string protocol = "iot:1";
public string node = "mobile";
public string _event = "";
public string[] targets = new string[] { "ALL" };

}
}

Look at the _event variable, I do not know how to create event – because it is reserved keyword. We will do a nasty hack.
Return to sendMessage and update it:


private void sendMessage(string action)
{
Protocol msg = new Protocol();
msg._event = action;

string json = Newtonsoft.Json.JsonConvert.SerializeObject(msg);
json = json.Replace("_", "");

UdpSocketClient client = new UdpSocketClient();
var msgBytes = Encoding.UTF8.GetBytes(json);

client.SendToAsync(msgBytes, "192.168.1.255", 5053);
}

This require another package Newtonsoft Json. Add it via NuGet manager. This package allows us to easily serialize object to JSON string. There is also a nasty hack with removing _.

Summary

We made a portable mobile application. It is rather ugly but works, even the IP s hard-coded 🙂 but it is my first Xamarin app.

I tested it on Android and Windows 10 Mobile, works perfectly.

And it is the first and last time I used xaml for UI.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s