Sunday, September 11, 2016

MT7688 Duo getting started

Now days I am putting together a basic kit for an IoT course that I am designing.
The kit consists of items purchased from Visha World.
This is what it looks like at the moment.


All of the above components - except MT7688 Duo - can be purchased online from Visha World. For MT7688 Duo, you can visit seeed studio and order it from them. Once I am done designing the course, the details will be available on our training website over at www.seekhow.in and the kit as a whole will be made available at www.vishaworld.com.

As of now, the kit consists of the following:

  1. MT7688 Duo [Buy]
  2. 4GB MicroSD Card
  3. 8 Channel Relay board controllable over USB [Buy]
  4. CH340G Based USB UART
  5. Breadboard [Buy]
  6. Breadboard patch cables 40 way Male to Female 200mm long [Buy]
  7. Breadboard patch cables 40 way Female to Female 200mm long [Buy]
  8. Breadboard patch cables 40 way Male to Male 200mm long [Buy]
  9. USB OTG Cable
  10. DHT11 Temperature Humidity Sensor [Buy]
  11. 0.96" OLED Display [Buy]
  12. microUSB cable for MT7688 Duo's Microprocessor
  13. miniUSB Cable for Relay Board


Step 1: Gaining access to the serial console.
The first thing I did when I got my MT7688 Duo was to get access to its console over UART. For that I used CH340G based USB-TTL convertor with its voltage set to 3.3V. Here is a photo and screenshot:



For wiring details, have a look at Seeed Studio's Wiki Page for MT7688 here.


Step 2: Connecting the MT7688 Duo as a client to your home's WiFi Connection
To know how to connect your MT7688 Duo to your home/office WiFi network, have a look at Seeed Studio's Wiki Page for MT7688 here.

Step 3: Mounting the microSD card
Insert the microSD card and then via the serial console, issue the commands:

cd /dev
mount -t vfat mmcblk0p1 /mnt/

Then issue the command:
df -h
and you will note the microSD card showing up in the list.


Friday, July 22, 2016

Simple chat server and client

Simple Chat IPv4 Server and Client code. Run the server on one computer and the clients on the same network. Whatever one client sents to the server, it is copied and sent to all the clients connected to it. The code is hosted on gist and embedded below.

Monday, May 30, 2016

Personal Analytics using DIY IoT devices and InitialState.com

Recently I have blogged about three DIY IoT devices that I have put up in my house. Some of these devices have been running for past 3 years and uploading data points to one of the three data brokers - Xively or ThingSpeak or Carriots. A few months ago I switch to InitialState.com which has a sleek interface and allows you to analyse your data in a much better visually intuitive way.

So with the following 3 devices collecting data using sensors from inside my house...

  1. Weather station outside - installed in my balcony (temperature, humidity, pressure, light)
  2. Ambient sensors inside the house next too the bathroom (temperature and humidity)
  3. Electrical Energy Meter - Monitoring voltages, currents etc on all 3 phases 


...here are the few insights that I gleaned on from analyzing the data:



Overview:


This is what my tiles app looks like with the various data stream being fed from the 3 IoT devices
Recently, InitialState.com made changes to their platform to allow decreasing the size of the tiles even further
This helps organize and fit in much more information on a single screen.
Lines app with all data streams activated. This gives you storage oscilloscope like functionality with cursors and zoom.


My electricity usage patterns:


This is the voltage of third electrical phase to which all my water heaters are connected.
I can check the days on which I used them (i.e. I took a bath) and
days on which I did not (i.e. I did not take a bath) and ... days
on which I used them twice or for longer duration (i.e. I had a guest stay over).
I was on vacation 7th may on wards, so no water heater usage during the period post that date

This is the second electrical phase to which my
kitchen appliances (microwave, washing machine and fridge) are connected.
The persistent square wave is my fridge's compressor turning on and off.
The spikes are the days on which I washed clothes.
The smaller spikes are when I used the microwave.

This is the voltage on the first phase of my electrical supply.
Lights and fans, TV, computer, router  are connected to these.
You can see the things been turned on and off - evident from discretization.

Zoomed out view of the total electrical energy consumed.
Obviously it would keep increasing over time.
I guess how it accumulates over time depends on the energy meter I am using.

If you zoom in, you can figure out the days (flat parts) when there was a
power failure for a few minutes

Same graph as above. Different color, more zoom.
Power failure is clearly seen

Citizen science - analyzing the weather:

 
Detecting Clouds
Ambient light being captured by the weather station installed outside.
Zoomed in to 4 days worth of data
As the Sun moves across the sky, it created a curve.
The curve is distorted at the top because there is a pillar in the balcony that
casts a shadow on the sensor. You will note that of the 4 days, the graph
on the third day is much more smoother.
This perhaps indicates that there were no clouds on that day

Daily Temperature/Humidity/Light cycles
When the sun is at its peak, the humidity is the least and temperature is maximum.

The days on which I took bath
Lines app showing readings from humidity sensor placed inside my house.
The peaks every now and then are the times at which I took bath - opening the
bathroom unleashes extremely humid air into the house.



Temperature cycling through the day
You can not the maximum and minimum temperature.
The daily temperature range is 10 degrees centigrade.
Also its getting cooler on an average.

As the sun rises (light sensor in red), temperature starts rising as well (temperature in orange)

Atmospheric Pressure cycles twice a day.
Not very clear from here, but unlike temperature, humidity and light which only cycle once a day,
atmospheric pressure goes through 2 peaks and troughs in a day.
No one taught me this at school

Outside temperature and outside humidity plotted together.
It is jst fascinating to look at. Nothing new there.

Plot of humidity levels inside and outside.
The inside humidity levels follows the ones outside.
Nothing much to see there. 
The inside temperature of an unoccupied house is the average of outside temperature.
I haven't been living inside the house for the few days that are covered in this graph.
The graph shows outside and inside temperature.
The outside temperature cycles daily.
The inside temperature on the other hand is a smooth curve which sort
of looks like the average value of the temperature outside.
The insulating effect of the house is responsible for that.



How to tell if an house is unoccupied by looking at inside temperature values
Inside temperature: On the days I was at home you can see a lot of ups and downs
But 7th May on wards, the inside temperature curves is smooth cause there
was no one to open and close the windows and doors.

Graph of inside temperature and inside humidity.
There are much more ups and downs when people are living in the house than when they are not.
Opening and closing the doors and windows causes those ups and downs.



Tuesday, May 24, 2016

SHT11 + Particle Photon (running matrixSSL) + InitialState.com


Now days microcontroller platform for IoT devices are becoming more and more powerful so much so that they can now sport an HTTPS stack and hence send telemetry to an HTTPS capable data broker like initialstate.com. Which means no need for any linux based gateway/hub - you can do away with your Raspberry Pi as a go between your microcontroller node and the internet.

You ask why would some one want to do that? Simple - lesser the number of components in your system, lesser the points of failure.

So, I wanted to explore if it was possible to use a Particle Photon to send data directly to initialstate.com and recently it just became possible when a few good folks ported an SSL library to Spark Photon.
My Particle Photon with SHT11



Steps:
  1. Get a Particle Photon and connect it to SHT11. SHT11 is a digital temperature and humidity sensor. It works at 3.3V logic levels and can be powered by the photon itself. The photon will draw power from any nearby device (computer, smartphone charger or router) which has a spare USB port. Here are the connections:
    Connection schematic
  2. Install the Particle app on your android phone and use it to create an account for yourself and link your particle photon to your home WiFi network.
  3. Get an initialstate.com account and create a bucket. Make sure to note down the two API keys (Access key and Bucket Key)
    Noting down your initialstate.com access keys
  4. Now open https://build.particle.io and login with your particle account. Create a new App. add two libraries to it: HTTPSCLIENT-PARTICLE and SHT1X
  5. Write the following code into the .ino file that has been created by default. Make sure to modify the code so that it has your own initialstate.com access keys.

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    #include "SHT1x/SHT1x.h"
    #include "httpsclient-particle/httpsclient-particle.h"
    
    
    
    //Initial State.com and HTTPS configuration START---------------->
    #define INITIALSTATE_ACCESS_KEY "243434gdfsgt43f43rfwp3"
    #define INITIALSTATE_BUCKET_KEY "GHDER34RF3NE"
    
    const bool g_https_trace = false;  // This controls debug info print to Serial
    const char host [] = "groker.initialstate.com";
    //const char ad_endpoint [] = "/api/events";
    const char se_endpoint [] = "/api/events";
    const int g_port = 443; // Don't change this, unless you know what you are doing
    static unsigned int freemem;
    bool g_https_complete;
    uint32 g_bytes_received;
    
    TCPClient client;
    
    // Replace XXXX...XXX with base64 encoding if your gf username:password
    // If you don't know how to generate the base64 encoding go here:
    //    http://www.tuxgraphics.org/toolbox/base64-javascript.html
    // CAUTION: Do NOT remove/replace the word Basic from the string above,
    //          it's part of http standard.
    unsigned char httpRequestContent[] = "POST %s HTTP/1.0\r\n"
     // "User-Agent: curl/7.38.0 \r\n"
      "User-Agent: MatrixSSL/" MATRIXSSL_VERSION "\r\n"
      "Host: groker.initialstate.com\r\n"
      "Accept: */*\r\n"
      "Content-Type: application/json\r\n"
      "X-IS-AccessKey: " INITIALSTATE_ACCESS_KEY "\r\n"
      "X-IS-BucketKey: " INITIALSTATE_BUCKET_KEY "\r\n"
      "Accept-Version: 0.0.4\r\n"
      "Content-Length: %d\r\n\r\n%s";
    
    //<----------------Initial State.com and HTTPS configuration END
    
    
    //SHT11 Temperature and Humidity Sensor START---------------->
    // Channel 1 is Temperature (deg C)
    // Channel 2 is Humidity (%)
    
    #define dataPin  D0
    #define clockPin D1
    
    SHT1x sht1x(dataPin, clockPin);
    //<----------------SHT11 Temperature and Humidity Sensor END
    
    
    void setup() {
      if (g_https_trace) {
        Serial.begin(9600);
      }
      httpsclientSetup(host, se_endpoint);
    }
    
    
    unsigned int nextTime = 0;    // Next time to contact the server
    int g_connected;
    char jsonBufARR[300] = {0};
        
    void loop() {
        String jsonBuf;
        unsigned int t = millis();
        if (nextTime > t) return;
    
        float temperature = sht1x.readTemperatureC();
        float humidity = sht1x.readHumidity();
        jsonBuf = "[";
        jsonBuf += "{";
        jsonBuf += " \"key\": \"Inside_Temperature\",";
        String Temperature_C(temperature, 4);
        jsonBuf += " \"value\": \"" + Temperature_C + "\"";
        jsonBuf += " },";
        jsonBuf += " {";
        jsonBuf += "\"key\": \"Inside_Humidity\",";
        String Humidity_Percent(humidity, 4);
        jsonBuf += " \"value\": \"" + Humidity_Percent + "\"";
        jsonBuf += " }";
        jsonBuf += "]";
        jsonBuf.toCharArray(jsonBufARR, 300);
        
    
        g_connected = client.connect(host, g_port);
        if (!g_connected) {
            client.stop();
            // If TCP Client can't connect to host, exit here.
            return;
        }
        g_https_complete = false;
        g_bytes_received = 0;
        int rc;
        httpsclientSetPath(se_endpoint);
        if ((rc = httpsClientConnection(httpRequestContent, jsonBuf.length(), jsonBufARR)) < 0) {
            // Failure
            if (g_https_trace) {
                Serial.print("httpsClientConnection Returned:\n");
                Serial.println(rc);
            }
            httpsclientCleanUp();
            return;
        } else {
            if (g_https_trace) {
                Serial.println("HTTPS Transaction Successful");
            }
            
        }
        
        client.stop();
        if (g_https_trace) {
            Serial.println("<<<<----------------------------------------New HTTPS Transaction ENDS\n\n");
        }
        nextTime = millis() + 40000;
    }
    

    This is how your Web IDE should look like.
    Note the place where you need to add your own initialstate.com Access keys.

  6. Download the firmware (using the Web IDE - over the air) into your photon and wait for a few seconds then open your initialstate.com tiles view, you note the data being uploaded every 40 seconds.
Here is what my lines app view on initialstate.com looks like, the "Inside_Temperature" and "Inside_Humidity" show the data sent by my Particle Photon to my Home bucket which also includes streams from various other IoT devices that I have installed in my home.


My Particle Photon and SHT11 is installed inside my house.
This is the lines app view showing temperature and humidity data graphed over the past two month

This lines app view shows only the "Inside_Temperature" stream.
I have been out on vacation and my house has been unoccupied since 5/7/2016.
Note how the temperature curve over latest 2 weeks is a smooth wave with
no dips and downward spike - probably a dynamic state of equilibrium established since
there is no one entering or leaving the house and the doors and windows are closed!


Notes:
  1. For background on how hubs are used to do HTTPS/TLS, read Your Very Own Raspberry Pi Smart Home Hub
  2. Webhooks when used with your Particle devices can bypass the use of Raspberry Pi kinda gateway/hub as well - AND THAT WOULD DEFINITELY BE A BETTER WAY to send data to initialstate.com than the one I have specified above because of one main reason - HTTPS stack uses up precious code space on your particle microcontroller which is not ideal, you need that re
  3. Arduino Yun has a microcontroller and a microprocessor (running Linux) on it. You can use that to send DHT11 readings to initialstate.com as well.
  4. I tested the above code on Particle Cores - The web IDE threw compilation errors. In case of Particle Core, you can use webhooks like so.
  5. Forum post regarding matrixSSL ported to Particle Photon by glowfi.sh team is here
  6. Github repository for https library for Particle Photon is here.

Friday, May 20, 2016

Configuring your OpenWRT router to use ExpressVPN to provide unrestricted internet access to all your devices

Problem statement:
I am in China. I have subscribed to ExpressVPN access to check my gmail and facebook. I have a pocket router (TL-MR3020). How can I use that VPN for all my devices (laptop, mobile, tab, Android TV box). TL-MR3020 can run OpenWrt. It has a USB port, an Ethernet port and 802.11bg WiFi

Here are the steps. They involve downloading packages to your OpenWrt router. OpenWrt repositories are blocked in China as well. So complete these steps in your home country before you fly to China. (If you are already in China, you can install the ExpressVPN client on your laptop, and share that VPN Connection with your OpenWrt Router. Refer to this blog post on steps on how to do that)

  1. Install OpenWrt on your TL-MR3020 router. (Refer to this blog post on how to do that - the latest version is a bit big and requires an external flash drive for extra memory size)
  2. Connect your OpenWrt router to unrestricted internet. Make sure you can access the router's console over SSH or serial (using PuTTY)
  3. Install OpenVPN packages on your TL-MR3020, issue the following commands using the console:
    # opkg update
    # opkg install openvpn-openssl luci-app-openvp ca-certificates
  4. Reboot the router.
  5. After this point, your router does not neet unrestricted internet access, you can now connect the TL-MR3020 router to the restricted network - just make sure your laptop and your router are on the same network. In my case I connected my TL-MR3020 to my set-top box which has a builtin WiFi router. The set top box has been provided by my Chinese ISP.
    My TL-MR3020 connected to my Chinese ISP's set top box
  6. Using a web browser, login to your ExpressVPN account and download the OpenVPN configuration file corresponding to the VPN server that you want to connect to. These .ovpn files are specific to your account and do not require modifications (like editing password or login). They will work as long as you keep renewing your subscription.

    I downloaded "my_expressvpn_uk_-_berkshire_-_2_udp.ovpn" for my use
    Downloading the .ovpn files
  7. Use WinSCP  to connect to your router and upload this .ovpn file to /etc/openvpn folder. You can upload more .ovpn files in case you think that you will need to switch servers in the future.
    uploading the .ovpn files to TL-MR3020 using WinSCP
  8. Configure the various files using nano editor over PuTTY SSH:

    /etc/config/wireless
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    config wifi-device 'radio0'
     option type 'mac80211'
     option hwmode '11g'
     option path 'platform/ar933x_wmac'
     option htmode 'HT20'
     option disabled '0'
     option channel '4'
     option txpower '15'
     option country 'US'
    
    config wifi-iface
     option device 'radio0'
     option mode 'ap'
     option ssid 'YOUR_SSID'
     option network 'wifi'
     option encryption 'psk2'
     option key 'YOUR_PASSWORD'
    
    /etc/config/network
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    config interface 'loopback'
     option ifname 'lo'
     option proto 'static'
     option ipaddr '127.0.0.1'
     option netmask '255.0.0.0'
    
    config globals 'globals'
     option ula_prefix 'fd59:92ba:e14c::/48'
    
    config interface 'lan'
     option ifname 'eth0'
     option proto 'dhcp'
    
    config interface 'wifi'
     option _orig_ifname 'wlan0'
     option _orig_bridge 'false'
     option proto 'static'
     option ipaddr '172.16.0.1'
     option netmask '255.255.255.0'
    
    config interface 'EXP_VPN'
     option proto 'none'
     option ifname 'tun0'
    

    /etc/config/firewall
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    config defaults
     option syn_flood '1'
     option input 'ACCEPT'
     option output 'ACCEPT'
     option forward 'REJECT'
    
    config zone
     option name 'lan'
     option input 'ACCEPT'
     option output 'ACCEPT'
     option forward 'ACCEPT'
     option network 'wifi'
    
    config include
     option path '/etc/firewall.user'
    
    config zone
     option name 'VPN_FW'
     option network 'EXP_VPN'
     option input 'REJECT'
     option output 'ACCEPT'
     option forward 'REJECT'
     option masq '1'
     option mtu_fix '1'
    
    config forwarding
     option dest 'VPN_FW'
     option src 'lan'
    
    config zone
     option name 'wan'
     option input 'ACCEPT'
     option forward 'REJECT'
     option output 'ACCEPT'
     option network 'lan'
    
  9. Issue the following commands to set Google DNS

    # uci add_list dhcp.lan.dhcp_option="6,8.8.8.8,8.8.4.4"
    # uci commit dhcp
    # reboot
  10. Using web login to LuCI on your OpenWrt router, configure a startup task instructing OpenVPN to initiate a VPN connection at bootup using the following lines:

    openvpn --cd /etc/openvpn --config /etc/openvpn/my_expressvpn_south_korea_udp.ovpn
    Configuring a startup task

    Please note that OpenVPN will try to connect to VPN server only once failing which it will
    stop trying. So you may need to reboot your router manually by power cycling if you arent able to access the internet.
  11. Now connect your devices to TL-MR3020's wifi signal and try accessing the internet.



Some more screenshots of LuCI's configuration pages - these correspond to the settings in the configuration files present in /etc/config








References:
  1. https://www.robertkehoe.com/2015/08/setup-openvpn-using-openwrt/
  2. https://www.loganmarchione.com/2014/10/openwrt-with-openvpn-client-on-tp-link-tl-mr3020/
  3. https://wiki.openwrt.org/doc/howto/vpn.client.openvpn.tun


Share your Laptop's ExpressVPN connection with your embedded development device while in China

Imagine you have an embedded development device (TL-MR3020 running OpenWrt in my case) and you are in China.  You want your embedded device to access unrestricted internet so that you can develop some apps for your router. You can use your laptop as a go between your home WiFi and your router. The laptop will initiate VPN connection and provide the internet access to your development device (TL-MR3020 in my case)
Our Chinese set top box which also provides internet over Wifi - it has a Wifi router builtin.

Here is my topology:


  • My laptop: Runs Windows 10 x64, ExpressVPN client and Tiny DHCP
  • My development device: Tplink TL-MR3020 running OpenWrt Chaos Calmer with rootfs mounted on external flash drive
  • Name of my WiFi adapter on my Windows PC: Wireless Network Connection
  • Name of my Ethernet adapter that I connect to my TL-MR3020: Local Area Connection
  • Name of the virtual TAP adapter created by ExpressVPN that I will share with my TL-MR3020: Ethernet (and NOT ExpressVPN - I know it might appear in some screenshots below, but that's not what we want to share)

My TL-MR3020 connected to my laptop's Ethernet port.
I want my TL-MR3020 (runs OpenWrt) to access internet unrestricted.
  1. Get a paid ExpressVPN account.
  2. Connect your Windows laptop to your home WiFi router - in my case the WiFi Router is built into the Cable TV set top box.
  3. Download and install ExpressVPN client. Login and test if VPN works on your laptop.
    ExpressVPN Windows client
  4. The VPN connects through WiFi. Our laptop's ethernet port is free. So connect a straight LAN cable between your TL-MR3020 router and laptop.
  5. Make sure the router is configured to receive an IP address over Ethernet using DHCP.
  6. Share your VPN connection. Express VPN creates a virtual TAP Ethernet adapter. We need to share that internet connection.
    Right click the TAP adapter
    Share it through the "Local Area Network" which is the ethernet port to which our TL-MR3020 is connected
  7. Run TinyDHCP server on your laptop. This will turn your laptop into a DHCP server and assign IP address to your TL-MR3020 when it requests it.
  8. Power on your TL-MR3020, wait for a while, then SSH into it over serial (if you have soldered a FT232RL widget to it) or using PuTTY over TCP/IP and check if it is able to access the internet using ping (# ping www.google,com).

    When the TL-MR3020 turns on, it requests the laptop for an dynamic IP address.
    That's when TinyDHCP server pops up a window into which we enter the appropriate settings
    to send to TL-MR3020.

  9. If the above step does not work, configure your development device to use Google's public DNS servers by editing /etc/resolv.conf 
    Editing resolv.conf to add entries for Google's Public DNS servers.

Sunday, May 15, 2016

Internet Connected Energy Meter

This is the final post in a series of post that explains how I installed an electrical energy meter in my house and connected  it to the internet.

Here are the steps involved:

  1. Installing a 3 phase energy meter in your home [Blog post here]
    (I used Selec MFM383C Modbus capable energy meter, connected it to my router using USB<>RS485 interface based on FT232RL and MAX485)
    Modbus capable energy meter
  2. Installing OpenWrt 15.05 Chaos Calmer on TP-LINK TL-MR3020 [Blog post here]
    (required adding a USB hub to it, a USB flash drive to hold the rootfs, an FT232RL widget  for getting console access to the router over serial and another FT232RL based USB<>RS485 UART for interfacing to the energy meter using modbus. Instead of TL-MR3020, you can use TL-MR3040 as well which has its own battery pack in it.)

    TL-MR3040 (White color) with a USB hub sporting an 8GB Flash drive and USB<>RS485
    convertor.

    A TL-MR3020 with a USB hub (Flash drive in one of the ports) and
    an FT232RL used to gain console access.
  3. Compiling the binaries for libmodbus and mfm383c [Blog post here]
      
  4. Install drivers for FT232RL based RS485 bridge, curl and some other important stuff on your router:
    # opkg update#  opkg install kmod-usb-serial-ftdi kmod-usb-acm kmod-usb-serial curl coreutils-stty usbutils libmodbus bash nano grep getopt ip-full syslog-ng
      
  5. Installing CA Certificates on your TL-MR3020 running OpenWrt
    We need HTTPS support to upload datapoints to initialstate.com, so to avoid the "(51) Cert verify failed: BADCERT_NOT_TRUSTED" error thrown by cURL, we need to install the certificates, do this by issuing the commands to your router:

    # opkg update
    # opkg install ca-certificates


  6. Sign up for an Initial State account.
      
  7. Write script to execute mfm383c.out, read all the registers from the energy meter over modbus and use cURL
    Script is appended below, place it in /root of your router. Make sure to use your own access key and bucket key from your initial state account and add them to the script accordingly.
      
  8. Finally add it to the crontab - use the web GUI and set the script to execute once every minute.
Configuring the router to run the script every minute

This is what my initial state tiles view looks like.
It not only has data coming in from my energy meter but also from my weather station.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/bin/bash

export SSL_CERT_DIR=/etc/ssl/certs


# InitialState Configuration:
INITIALSTATE_ACCESS_KEY="YOUR ACCESS KEY"
INITIALSTATE_BUCKET_KEY="YOUR BUCKET KEY"

register_names=( "KWH" "V1N" "V2N" "V3N" "I1" "I2" "I3" "FREQ" "KW_TOTAL" "KVA_TOTAL" )
array_len=${#register_names[@]}

logger 'Reading Registers from Selec MFM383C over RS485/Modbus'
echo 'Reading Registers from Selec MFM383C over RS485/Modbus'
echo 'Baud 9600 | Data bits 8 | Parity bits N | Stop bits 1 | Port /dev/ttyUSB0'
echo 'Slave ID 1 | Response timeone 1 second | Byte timeout 1 second'
echo '--------------------------------------------------------------------------'
echo ''


# ------ Initial State -------------------------------------------------------------

# Prepare cURL HTTP PUT data
DATA_JSON="["

for (( i=0; i<${array_len}; i++ ));
do
 # Send two Ping request packets and 4 seconds timeout
 register_value=$(/root/mfm383c.out -b 9600 -r ${register_names[$i]})
 return_value=$?
 case $return_value in
  0)  #Register read successfully
   logger "Selec MFM383C register read successfully ${register_names[$i]} = $register_value"
   DATA_JSON="$DATA_JSON"$'\n'"     { \"key\" : \"Electricity_${register_names[$i]}\","
   DATA_JSON="$DATA_JSON"$'\n'"      \"value\" : \"$register_value\""
   if [ $((i)) = $((array_len-1)) ]; then
    DATA_JSON="$DATA_JSON"$'\n'"    }"
   else
    DATA_JSON="$DATA_JSON"$'\n'"    },"
   fi
   ;;
  1)  #Reading register failed: Incorrect command line parameters
   logger "Selec MFM383C register read error: Incorrect command line parameters"
   ;;
  2)  #Reading register failed: Modbus library error
   logger "Selec MFM383C register read error: Modbus library error"
   ;;
  3)  #Reading register failed: Modbus serial error
   logger "Selec MFM383C register read error: Modbus serial error"
   ;;
  *)  #Reading register failed
   logger "Selec MFM383C register read error"
   ;;
 esac
done
DATA_JSON="$DATA_JSON"$'\n'"  ]"

echo $DATA_JSON

# execute cURL
curl --max-time 5 \
--include \
--request POST \
--header "Content-Type: application/json" \
--header "X-IS-AccessKey: $INITIALSTATE_ACCESS_KEY" \
--header "X-IS-BucketKey: $INITIALSTATE_BUCKET_KEY" \
 --header "Accept-Version: 0.0.4" \
 --data-binary "$DATA_JSON"  \
'https://groker.initialstate.com/api/events'