Thursday, 3 May 2018

IBM API Connect Naming Conventions

**NOTE: Though I am an IBMer, these are naming conventions I personally endorse but are not necessarily endorsed by IBM as an organisation as per all posts on my blog**

Introduction

IBM API Connect has a host of free text variable, parameter, profile and component names. Whilst these are and can be named whatever you like, it is good to follow some uniform naming standards.

Often each new business, value stream, brand, department and individual people will have specific ways in which they like to name. This leads to every object being named different for each new department and team. To alleviate this, I have created the following naming conventions which can be used.

Table of Contents

Case Study

All examples described in this document will reference an imaginary Commercial Bank called UKBank that specialises in Mortgages, Loans and Current Accounts, they also provide open APIs for bank locators etc.

The Bank is using Organisations as their environments i.e. SIT01, OAT01, NFT01, LUAT01, PROD01. Their catalogs relate directly to their specialisations with spaces in Current Accounts to isolate traffic for their payments from balance enquiries.

Naming Objects as ‘Default’

Where possible, no object in the API Connect Cloud should be left with a default name of ‘Default’. This causes confusion, makes email notifications difficult to follow and can lengthen routine maintenance and management processes as an understanding of what each element does is made apparent.

Display Names and Object Names

In API Connect, most objects have both a display name - sometimes referred to as a Title - and a ‘name’ which refers to the object name. Where appropriate, both display and functional names have been given.

1      API Development

1.1   APIs

There are many well documented conventions for naming APIs and will often follow company preference. 
IBM have released a guide for APIs in past redbooks: Getting Started with IBM API Connect Concepts and Architecture Guide (http://www.redbooks.ibm.com/redpapers/pdfs/redp5349.pdf) 
Additionally, there are articles that describe API needs around versioning and standard formatting of naming, versioning and url etc. (https://www.ibm.com/developerworks/library/mw-1710-phillips/index.html)
https://api.ukbank.co.uk/mortgages/v1.0/rates
https://api.sandbox.ukbank.co.uk/loan/v1.1/quote  
https://developer.ukbank.co.uk/v1.0/balance

1.2   Product

Products contain a logical grouping of APIs which will be callable once a Developer Organisation has subscribed to its plan. The Product should accurately describe the purpose of the collection of APIs. 

Product names should include dashes and not underscores and should not contain numbers. Version numbers should not be defined in the Product name, this causes confusion as it is static against the dynamic version number that displays next to the Product.

If there is a need to differentiate between brands these are appended in brackets at the end of the product.

Title
Name
Current Account Information (England)
current-account-information-england
Current Account Information (Scotland)
current-account-information-scotland
Mortgage Offers (England)
mortgage-offers-england
Mortgage APR (England)
mortgage-apr-england
Mortgage Payments (UKBank)
mortgage-payments-ukbank

1.3   Plans

Plans are used for rate limiting of API Calls and monetization of APIs. Developer Organisation subscribe an Application to a Plan, not a Product. Each product can have multiple plans which will have different costs and potentially rate limits. Additionally, different plans may conform to predefined contract agreements between third parties, public and internal users.

When an Organisation has a predefined, well documented and well understood convention for logical grouping of APIs and their limits, these should be continued in plan names. This would typically map to a standard selection of upgrades.

Plan 1 - Title
Plan 1 - Name
Plan 2 - Title
Plan 2 - Name
Plan 3 - Title
Plan 3 - Name
Basic
basic
Standard
standard
Advanced
advanced
Bronze
bronze
Silver
silver
Gold
gold
Small
small
Medium
medium
Large
large

2      Topology

2.1   Provider Organisations

Provider Organisations might be named after an environment i.e. SIT01 or by an Organisations business unit i.e. UK Sales, UK HR.

An Organisations display name may be several words, each beginning with a capital letter. Its logical name must represent the display name, it must not contain spaces but instead should use a dash rather than an underscore. For best display and reference, it is recommended that the Organisation not be any more than 2 words and 15 characters (Maximum length: 81 characters).

Where multiple environments may exist of the same type i.e. System Integration Test, the environments unique identifier should be two numbers after the environments abbreviations beginning at ‘01’ through ‘99’.

Display Name
Name
OAT01
oat01
SIT01
sit01
SIT02
sit02
LUAT01
luat01
UK Sales
uk-sales
UK HR
uk-hr

2.2   Catalog

Catalogs provide a logical separation for Products and their APIs with an Organisation. They also determine the developer portals that will be used for subscription of Plans within APIs as catalogs can have a single Developer Portal Site and therefore each catalog can push only to a single portal site. The actual name given to a catalog depends on the chosen distribution of Products, APIs and intended use of Organisations, though it commonly becomes split by a brand or value stream.

Catalogs names should be a single descriptive word. However, if a double worded Catalog is used it should not use camel-case and should have capitals for the first letter of each word and a space used for the display name. 

Display Name
Name
Mortgages
mortgages
Open
open
Loans
loans
Current Accounts
current-accounts

2.3   Spaces

Spaces provide a separation of Products and APIs within a single Catalog. Each space should describe the separation it is bringing with its name. 

Spaces names should be single word and descriptive. However, if a double worded Space is used it should not use camel-case and should have capitals for the first letter of each word and a space used for the display name. 

Display Name
Name
Balance
balance
Payments
payments
England Stores
england-stored
England Regulations
england-regulations

2.4   Communities

2.4.1     Developer Organisations

Developer Organisations can be created both on a Portal site and also on the management server. Typically, the Portal Site would be explored by external entities either external to the business itself or external to Provider teams, brands and value streams. Internal Developer Organisation such that have their Developer Organisations created for them will be defined in the API Manager WebUI. 

The naming convention to be applied here should follow existing internal naming solutions for applications. Where no existing convention exists, the format should follow the format of Organisation-ValueStream-TeamName.

Developer Organisation
UKBank-HR-Compensation
UKBank-Mortgages-Test
UKBank-Mortgages-Development
UKBank-Mortgages-View

2.4.2     Applications

Applications should be created with its goal and purpose in mind. The name of these applications should be concise, should all be lower case and obvious what the application does.

Title
hr-employee-payment
hr-employee-illness
mortgage-test-ivt001
mortgage-test-ivt002
mortgage-test-ivt003
mortgage-test-endtoend

2.5   Management Services

2.5.1     Service Name

In IBM API Connect v5, there is a single management service called Management. This cannot be changed. 

2.5.2     Server Name

Server names should reference the server address/hostname being used. This helps easily identify management servers and issues that may arise i.e. dissociation. 

Where server names already exist within the company or organisation, this standard should be used and the name used throughout. This consistency allows interdepartmental teams to quickly understand and identify issues.

Server Name
Server Address
MGR0012
10.132.41.12 mgrsrvr0012.prod.machine

2.6   DP Services

2.6.1     Service Name

Services should be named relating to the Organisation they are being used by and should be named in a descriptive form of the domain they are representing. This service will be used by catalogs and spaces to define the gateway services they will use, so a descriptive name is important.

Title
SIT01 Mortgages DP Service
OAT01 Current Account Payments DP Service
PROD01 Open APIs 

2.6.2     Server Name

Server names should reference the Organisation or Domain they are being used for and should be identifiable to the server they are representing to avoid confusion for debugging. We use gateway identifiers to precede the server identifier.

Server Name
Server Address
SIT01 GWY0022
10.132.41.22 gwysrvr0022.prod.machine

2.6.3     Extensions

Extensions are deployed to a single domain. They should include a version number which can be incremented as and when changes are made. Alternatively, or in conjunction with the version number, a date stamp may be appended to the end of the string to further describe when the extension was compiled. Names should be descriptive of the function being performed, should not contain spaces but instead dashes. The file should use full words and not abbreviations.

Filename
api-certificate-updates-v1.0.zip
api-certificate-updates-20180101-0323.zip
api-certificate-updates-v1.0-20180101-0323.zip

2.7   User Registries

A User Registry should be easily identifiable to anyone looking at the system. Typically, it would describe what component it is for, where the registry is based and then the fact it is a user registry.

The name cannot contain spaces, should be entirely in lowercases but should be shorter than the Title/Display Name. The registry location and “user registry” should be condensed to just the first letter of each.

Display Name
Name
API Manager Local User Registry
api-manager-lur
Cloud Manager Docker User Registry
cloud-manager-dur 

2.8   Roles

Each role within API Manager can have multiple words for its Title/Display Name to a maximum of 81 characters (to be represented equivalently in the name). These should describe the type of permission being given.

The name must be lowercase and use dashes instead of spaces.

Display Name
Name
Community Viewer
community-viewer
Role Assigner
role-assigner 

2.9   TLS Profile

TLS profiles can be used for communication with the API Connect Cloud Manager and the Gateway or for a TLS handshake with a load balancer. These cloud-based TLS Profiles are defined in the Cloud Manager. 

Additionally, TLS profiles can be defined in the API Manager to be used by APIs to call either other APIs on the same gateway or some form of implementation layer downstream such as an internal load balancer or microservice.

2.9.1     Cloud Console

The name given for Cloud based TLS Profiles should have the following format; component-tls-side-profile, component relates to where the profile is used, and side is whether it is a server or client profile. The Display Name/Title is the same but with spaces instead of dashes.

Display Name
Name
Default TLS Server Profile
default-tls-server-profile
SNI TLS Client Profile
sni-tls-client-profile

2.9.2     APIs

TLS Profiles to be used by APIs for handshakes to endpoints should have the following format; purpose-tls­-location. Where purpose should show the intended use of the profile and location should describe the endpoint where the handshake will occur. The Display Name/Title is the same but with spaces instead of dashes.

Display Name
Name
Authorise API TLS IHS
authorise-api-tls-ihs

3      Developer Portal

The developer portal is a server which stored all the information about each of the Clouds portal sites. There are limited objects that require naming conventions within the Portal such as Roles, Page Names and Drupal Modules.

3.1   Roles

Roles should follow the rules already defined earlier in the document: Roles. 

3.2   Developer Portal Modules

Modules within the Developer Portal allow additional functionality with the Portal Site such as configuration of LDAP for portal delegated user registry, live chat functions, OpenID Connect and many more.

Module names within the Developer Portal should follow Drupal Standards. 

4      v2018.x

4.1   Availability Zone

Availability Zones should be descriptive and are organised by regions, global separation, or for physical/logical separation of datacentres. The Title can use spaces, capitals, lowercase etc. but a short one or two-word title is preferred. Abbreviation may be used

Title
Name
US Availability Zone
us-availability-zone
Hampshire Availability Zone
hants-availability-zone
Newport Availability Zone
newport-availability-zone
LDN South Availability Zone
london-south-availability-zone

4.2   Portal, Analytics and Gateway Service(s)

Services should describe the type of service and match the location for the availability zone. There should be no spaces and each new word should start with a capital letter. Abbreviations should match those in the Availability Zone.

Title
Name
USPortal
us-portal
USGateway
us-gateway
HampshireAnalytics
hants-analytics
LDNSouthPortal
ldn-south-portal

4.3   OAuth Provider

OAuth Title should match the OAuth Provider being used exactly.

Title
Name
Zendesk
zendesk
Ubuntu One
ubuntu-one


Tuesday, 30 January 2018

Football Match - Using football simulation engine

I recently created a football simulation engine for npm which I talked about here.

I also posted a youtube video of me demonstrating the code, and after some interest I thought I would upload the helper code I used in order to visualise the match!

You can access the github page here: https://github.com/GallagherAiden/footballsimulationexample



Here's the read me:
# Football Simulation Example

## Install
1. Download the project onto your system ({dir})
2. cd {dir}
3. run ``npm install``
---
## Run the Game
1. load your team into the {dir}/teams directory (you can use an existing team as an example)
2. in '{dir}/server.js' change either
```
readFile("teams/team1.json").then(function (team1) {
```
to your newly created .json file i.e.
```
readFile("teams/myTeam.json").then(function (team1) {
```
3. Set the pitch size by changing the ``pitchWidth`` and ``pitchHeight`` in '{dir}/server.js'
*Note: Any changes will need changes made to the start positions of the players*
4. run ``npm start``
5. Go To ``http://localhost:1442/match.html``
---
## Playing A Match
1. Press ``start match``
- This starts a new match where the pitch size is displayed on the screen and the players are in their correct positions.
2. Press ``play match``
- This runs '10' iterations, moving the players and give iteration logs for each iteration.
i.e. `Iteration 50: Closest Player to ball: Louise Johnson,Closest Player to ball: Aiden Smith`
3. Press ``play match`` until the iterations reach 5,000
- We can make this quicker by changing the number of iterations per "play" in {dir}/public/js/match.js
```
function getMatch() {
var iterations = 10;
for (i = 0; i < iterations; i++) {
movePlayers("/movePlayers");
}
}
```
to
```
function getMatch() {
var iterations = X;
for (i = 0; i < iterations; i++) {
movePlayers("/movePlayers");
}
}
```
where X is the number of iterations to do at a time.
4. Press ``start second half``
- This flips the players to opposite sides
5. Press ``play match`` until the iterations reach 10,000
6. Record the results

Game Example Results:
Match 1 - Team1: 5 - 3 :Team2  (same json)
Match 2 - Team1: 3 - 4 :Team2  (same json)
Match 3 - Team1: 9 - 2 :Team2  (same json)
Match 4 - Team1: 2 - 5  :Team2  (team2 higher skills)
Match 5 - Team1: 0 - 7  :Team2  (team2 higher skills)
Match 6 - Team1: 8 - 1 :Team2  (team1 higher skills)
Match 7 - Team1: 3 - 0 :Team2  (team1 higher skills)

Have fun! Let me know if you need any help: aiden.g@live.co.uk


Thursday, 25 January 2018

Node JS Football / Soccer Simulation Engine Module

Football Simulation Engine - Node Module

As previously mentioned in my blog HERE, I had been looking to design and build a football manager game, with the main purpose being to improve my JavaScript (JS) and node (Node JS) skills. I soon found there were no existing node package modules (npm) that could provide a simulated match result.

I posted on a few sites to try and see if anyone had done this before - there’s no point repeating work is there? After finding nothing specific that matched my purpose I went on ahead and built my prototypes which consisted of two random numbers and a little use of player skill to create results (see previous blog), but it didn’t really fit the bill for a football manager games back end as it didn’t take other factors into consideration.

So, I went ahead and built my own, and as of today it is now available on the npm website HERE or run 
          npm install footballsimulationengine

How does it work?
Great question, glad you asked. Basically, you provide it with two JSON strings, each its own team and requiring a specific set of JSON objects. This includes team name, players, player positions, skills and each players starting position.
Example:
{
  "name": "Team1",
  "players": [{
      "name": "Player",
      "position": "GK",
      "rating": "99",
      "skill": {
        "passing": "99",
        "shooting": "99",
        "tackling": "99",
        "saving": "99",
        "agility": "99",
        "strength": "99",
        "penalty_taking": "99",
        "jumping": "300"
      },
      "startPOS": [60,0],
      "injured": false
    }...],
  "manager": "Aiden"
}

Key things to remember:
·      Each team MUST have 11 players
·      The code currently does not check these parameters, so the skills SHOULD be between 1 and 100.
·      Except for “jumping” which is intended to be the maximum jump height of the player in centimetres.
·      Start Position should between you pitch Sizes Width and half of the pitch length. The code deals with switching their start position side. E.g if my pitch size is [120, 600], “startPOS” SHOULD BE [0-120, 0 - 300].

The other thing we will need to start a game/match is pitch size, which is shown in [width, height] where the pitch is intended to be taller than it is wide, like below.

PIC

Example Pitch JSON:
{
            "pitchWidth": 120,
            "pitchHeight": 600
}

We feed these three JSONs into the initiate function like so:

Example:
initiateGame(team1, team2, pitch).then(function(matchDetails){
  console.log(matchDetails);
}).catch(function(error){
  console.error("Error: ", error);
})

what we get back is a super larger JSON with both teams, their originPOS (so we can get them back to their original position), relativePOS (so we know where they’re heading towards), and a whole bunch of match details such as the score, number of shots and importantly, where the ball is, ball direction.

The main idea is that the game runs in iterations this allows the client using the simulation engine to change players throughout the game, set up the game in certain positions.

Playing iterations is then as simple as running that big old outputted JSON back into a play iteration function which in turn, gives an updated big old output JSON.

Example:
playIteration(matchDetails).then(function (matchDetails) {
  console.log(matchDetails);
}).catch(function(error){
  console.error("Error: ", error);
}

Example Output:
{ kickOffTeam:
   { name: 'Team1',
     players:
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ],
     manager: 'Aiden'
     intent: 'defend' },
  secondTeam:
   { name: 'Team2',
     players:
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ],
     manager: 'Joe',
     intent: 'attack' },
  pitchSize: [ 120, 600 ],
  ball:
   { position: [ 76, 314 ],
     withPlayer: true,
     Player: 'Joe Bloggs',
     withTeam: 'Team2',
     direction: 'south' },
  half: 1,
  kickOffTeamStatistics:
   { goals: 0,
     shots: 0,
     corners: 0,
     freekicks: 0,
     penalties: 0,
     fouls: 0 },
  secondTeamStatistics:
   { goals: 0,
     shots: 0,
     corners: 0,
     freekicks: 0,
     penalties: 0,
     fouls: 0 },
  iterationLog:
   [ 'Closest Player to ball: Aiden Gallagher',
     'Closest Player to ball: Joe Bloggs' ] }

An important feature here is the “iterationLog” which gives an overview of what has happened during that iteration. i.e. someone has passed the ball, someone has taken a shot, scored, freekick awarded, penalty taken, a throwin given and taken.

Finally, the last function that can be played is switch sides of the teams that are playing, i.e. after half time or if running into extra time.

Example:
startSecondHalf(matchDetails).then(function (matchDetails) {
  console.log(matchDetails);
}).catch(function(error){
  console.error("Error: ", error);
}

TL;DR / Overview:
·      Three function; initiateGame - needs two team JSONs and a Pitch Details JSON, playIteration - takes the output from initiate game and updates one movement of each player, startSecondHalf - switches the sides the players are on.
·      All three functions are return promises
·      JSON isn’t checked so make sure you’ve got it right
·      Recommended match length is 10,000 iterations.

If you’d like help setting up, have some general questions please feel free to comment below and I’ll get back to you ASAP.

Improvements:
This code is setup on a public Github which you can find HERE and I’m hoping people who use the module (if anyone) will help me improve it! You can raise issues HERE but otherwise please get in touch by email: aiden.g@live.co.uk

Visual Example:
For those who want to see, here is a youtube video of the game being used in an example I have set up. Feel free to get in touch and I can send you the "manager" setup and some instructions. 


Wednesday, 29 November 2017

Motion Detector using a PhotoResistor and Arduino

I recently brought two "WeMos D1 WiFi Uno ESP8266 ESP-12E Development Board" hoping to get my first connectivity of two arduino systems via wifi.

Getting the WeMos D1's working

The first task is to set up the arduinos. I could write out how in full, but there's no point in reinventing the wheel, especially when the instructables website does such a good job here:

Once we have this setup its important to understand how we get that connectivity to the internet, what code we need and what the errors and status codes we might see in order to handle them in the code. The best link I have found, or the simplest for Connecting Arduino to Wifi (including status codes) is the one below.

However, the easiest way to get something working straight away is to use: http://www.esp8266learning.com/wemos-webserver-example.php all that is needed is to set your wifi name and password, upload to your Arduino and your done. Follow the IP address that is printed on the serial monitor and you'll have a webpage where you can turn on and off the light of the arduino. 

Try it with any webpage viewable device connected to the same network and voila!

Do this with both Arduino's. One of the Arduino's will be used as a web server and the other will be used to send the sensor information to switch the light on, on the web server in order to "Alert" someone watching the server Arduino that someone has passed the sensor that could be in another room.

Setting up a sensor to output analog (Alert Arduino)

For this we will need;
 - 1 PhotoResistor
 - 3 Male to Male Jumper Cable
 - 1 Resistor
 - 1 Breadboard

We plug the PhotoResistor into the breadboard on one of the centre areas, one leg will be connected to a positive 5V charge from the Arduino. The other will have a resistor across it into a new line and also a male to male jumper cable into one of the analog pins. The final piece is to connect the other end of the resistor to GND (ground).
The sensor will be pointing off the table towards where you want to monitor
We need to add the variable for the photoResistor. 

Before the Setup Code we add:
int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor
Within the loop:
sensorValue = analogRead(sensorPin);
Serial.println(sensorValue);

The information for this was taken from here: https://www.arduino.cc/en/Tutorial/AnalogInput
Once this runs we will start to see the unhindered sensor reading. In my case, this was around 355 - 380 and when covered by hand close and far the readings varied from 150 - 350. 

We can then add some code to the loop to turn the light on/off depending on the value returned by the sensor.
   if(sensorValue > 350){
      //turn light off
   }else{
      //turn light on
   }

Waiting for the Alert (Server Arduino)

We need to add the listener to turn on the light when the sensor is triggered.

In the "match request" section underneath the /LED we need to setup actions when the sensors alert.
  if (request.indexOf("/sensor=ON") != -1){
    digitalWrite(ledPin, HIGH);
    value = LOW;
  }
  if (request.indexOf("/sensor=OFF") != -1){
    digitalWrite(ledPin, LOW);
    value = LOW;
  }
Upload.

To test we can go to 
IPAddress:/sensor=ON
and then
 IPAddress:/sensor=OFF
on a network connected device. We should see the server Arduino's light turn on and then off. 

Posting an Alert when the sensor is triggered (Alert Arduino)

After a little google, the best Arduino POST example I could find using the examples we have was the answer by "stiff" on the following stack overflow question: https://stackoverflow.com/questions/3677400/making-a-http-post-request-using-arduino

Where we need to add;
   #include <ESP8266HTTPClient.h> 
   //inside the loop
   HTTPClient http;    //Declare object of class HTTPClient
   http.begin("http://IPAddress/sensor=OFF");      //Specify request destination
   http.addHeader("Content-Type", "text/plain");  //Specify content-type header
   int httpCode = http.POST("Message from ESP8266");   //Send the request
   String payload = http.getString();                  //Get the response payload

   Serial.println(httpCode);   //Print HTTP return code
   Serial.println(payload);    //Print request response payload
   http.end();  //Close connection
We can then use the:
 http.begin("http://IPAddress/sensor=ON");
with the sensorValue IF statement we made earlier.
if(sensorValue > 350){
   http.begin("http://IPAddress/sensor=OFF");      //Specify request destination
 }else{
   http.begin("http://IPAddress/sensor=ON");
  }
We have now completed the minimum viable product. I will share the full source code below as well as a video of the result. If you have any questions or would like the source code directly feel free to comment!
*UPDATE: below the original source code is an adapted piece of code which is much quicker and more responsive! enjoy!

Full Source Code: 

Alert Arduino: (With Sensor)

#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>

const char* ssid = "XXX";
const char* password = "YYY";

int ledPin = D5;
int sensorPin = A0;
int sensorValue = 0;

void setup() {

  Serial.begin(115200);                 //Serial connection
 
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);   //WiFi connection

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

}

void loop() {
   sensorValue = analogRead(sensorPin);
   Serial.println(sensorValue);
   if(WiFi.status()== WL_CONNECTED){   //Check WiFi connection status

   HTTPClient http;    //Declare object of class HTTPClient
   if(sensorValue > 350){
   http.begin("http://
IPAddress/sensor=OFF");      //Specify request destination
   }else{
   http.begin("http://IPAddress/sensor=ON");
   }
   http.addHeader("Content-Type", "text/plain");  //Specify content-type header
   int httpCode = http.POST("Message from ESP8266");   //Send the request
   String payload = http.getString();                  //Get the response payload

   Serial.println(httpCode);   //Print HTTP return code
   Serial.println(payload);    //Print request response payload
   http.end();  //Close connection

 }else{

    Serial.println("Error in WiFi connection");

 }

  delay(10);

} 
Server Arduino:

#include <ESP8266WiFi.h>

const char* ssid = "XXX";
const char* password = "YYY";

int ledPin = D5;
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  delay(10);


  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.print("Use this URL : ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");

}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }

  // Read the first line of the request
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();

  // Match the request

  int value = LOW;
  if (request.indexOf("/LED=ON") != -1) {
    digitalWrite(ledPin, HIGH);
    value = HIGH;
  }
  if (request.indexOf("/LED=OFF") != -1){
    digitalWrite(ledPin, LOW);
    value = LOW;
  }
  if (request.indexOf("/sensor=ON") != -1){
    digitalWrite(ledPin, HIGH);
    value = LOW;
  }
  if (request.indexOf("/sensor=OFF") != -1){
    digitalWrite(ledPin, LOW);
    value = LOW;
  }



  // Return the response
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); //  do not forget this one
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");

  client.print("Led pin is now: ");

  if(value == HIGH) {
    client.print("On");
  } else {
    client.print("Off");
  }
  client.println("<br><br>");
  client.println("Click <a href=\"/LED=ON\">here</a> turn the LED on pin 5 ON<br>");
  client.println("Click <a href=\"/LED=OFF\">here</a> turn the LED on pin 5 OFF<br>");
  client.println("</html>");

  delay(1);
  Serial.println("Client disconnected");
  Serial.println("");

}
Results:


UPDATE: From the above video we can see that the response is pretty slow with the code we have. To fix this I have edited the "Alert Arduino" code. Below is the results of changes made (below that will be the code).


Video Links: https://www.youtube.com/watch?v=Pfqs-WN9OiQ
                      https://www.youtube.com/watch?v=iTQJmba_wcw

Updated Code:

Alert Arduino: (With Sensor)
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>

const char* ssid = "XXX";
const char* password = "YYY";

int ledPin = D5;
int sensorPin = A0;
int sensorValue = 0;
int sensorOn = 0;
int currentSensor = 0;

void setup() {

  Serial.begin(115200);                 //Serial connection
 
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);   //WiFi connection

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

}

void loop() {
   sensorValue = analogRead(sensorPin);
   Serial.println(sensorValue);
   if(sensorValue > 350){
    sensorOn = 0;
   }else{
    sensorOn = 1;
   }
 
   if(WiFi.status()== WL_CONNECTED){   //Check WiFi connection status

   HTTPClient http;    //Declare object of class HTTPClient
 
   if(currentSensor == 1 && sensorOn == 0){
 
    currentSensor = 0;
    http.begin("http://IPAddress/sensor=OFF");      //Specify request destination
    http.addHeader("Content-Type", "text/plain");  //Specify content-type header
    int httpCode = http.POST("Message from ESP8266");   //Send the request
    http.end();  //Close connection
 
   }else if(currentSensor == 0 && sensorOn == 1){
 
    currentSensor = 1;
    http.begin("http://IPAddress/sensor=ON");
    http.addHeader("Content-Type", "text/plain");  //Specify content-type header
    int httpCode = http.POST("Message from ESP8266");   //Send the request
    http.end();  //Close connection
 
   }else{
 
    //do nothing
 
   }
   //String payload = http.getString();                  //Get the response payload
   //Serial.println(httpCode);   //Print HTTP return code
   //Serial.println(payload);    //Print request response payload

 }else{

    Serial.println("Error in WiFi connection");

 }

  delay(500);

}

You don't need a PHD to open a .phd file!

Today I was looking at some Java Core dumps on a system and wanted to start debugging to see what was causing an apparent memory leak. All was going well until I was led to:
  /log/javacore-filename.phd
I hadn't stumbled across a Portable Heap Dump (phd) before, so I started to have a little google as to how I could open it but couldn't find a command line answer to my problem. Apparently no conversion will get me what I want and I'll have to use a set of tools.

One of the first things that showed up was "IBM Memory Analyzer*" which gives analysis on heap/core dumps. To install you can have a stand alone application but it more conveniently comes as a plugin to be installed directly into an Eclipse runtime.
    http://www.eclipse.org/downloads/eclipse-packages/ 

*Being an IBMer myself I was inclined to use this since its one of our own products.*

To install you simply open eclipse and go to: help -> eclipse marketplace -> search for: "memory analyser" and select go -> install -> follow instructions and restart eclipse

I thought, brilliant I should be able to load the .phd and get the data I need. However, when I tried to load my file I got:
Error opening heap dump 'javaheapdump-user-cmc.phd'. Check the error log for further details.
Error opening heap dump 'javaheapdump-user-cmc.phd'. Check the error log for further details.
Not a HPROF heap dump (java.io.IOException)
Not a HPROF heap dump
After a little more google investigation I found I needed a little extra component called "IBM Monitoring and Diagnostic Tools for Java" or "IBM DTFJ" for short. This works on top of memory analyser and will allow us to open the phd file.

To download it go to: help -> Install new software -> Select the add button next to the "work with" text bar. -> In both boxes type: http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/runtimes/tools/dtfj/ -> toggle "IBM Monitoring and Diagnostic Tools" -> install -> follow instructions and reset eclipse.

Now when you go to open the .phd file, memory analyser will be able to find it and will use DTFJ to open it. From here we can get component reports and leak suspects.