This Custom Web Page Tutorial shows you the step-by-step process of creating a custom web page. You will learn how to customize a Simple Sensor web page to allow you to read and write datapoints for your device, an FT 6050 EVB (refer to the Setting up an Internal Application Program Example Network section for more information about this evaluation board) or a SmartServer internal app.
The tutorial web page source code files (SimpleSensor) are written for the FT 6050 EVB with the NcMultiSensor application (EVB default image) with a single device called "Sensor1". You will be modifying the source code to use other datapoints on the EVB, or you can use datapoints from one of your devices or a SmartServer internal app.
A SmartServer internal app called "UI Test Tester" is provided for those who do not have any devices but still want to learn how to create a custom web page. When using this internal app, you will use two of the datapoints for your initial custom web page. You can also add other datapoints on the "UI Test Tester" app.
The Simple Sensor web page source files are used as a starting point for developing a custom web page. See the Simple Sensor Web page for more information about how this example web page works.
This section consists of the following:
Requirements
To get started, you will need the following:
- SmartServer IoT 2.6 or higher
- SFTP program, such as WinSCP or CoreFTP
- Terminal emulation program, such as Putty or TeraTerm
- Web-page editor, such as Visual Studio Code, Windows Code Writer, a full web-page editor, or any other text editor
- USB-to-MicroB USB cable to connect to the SmartServer console port
- A device (your device or a FT 6050 EVB) or use the provided uiTestTester internal app
Getting Started Instructions
- Download the following files to your computer by clicking the following link SmartServer-IoT Example Repo.
Simple Sensor Web Page – which you will modify (Github under iot/smarterver-iot/web-pages).
- uiTestTester Internal App – optional SmartServer internal app you can use for this tutorial.
- UI Test Target App.zip – contains the internal app and documentation (Github under iot/smarterver-iot/apps/Example Support Files).
- uiTestTarget.dtp – provide the Resource files, XIF and DLA files (Github under iot/smarterver-iot/apps/Example Support Files).
- CustomWebPageTutorialSolutions – provides the solutions for this tutorial (Github under iot/smarterver-iot/apps/web-pages).
- uiTest1 – solution for uiTestTarget for the datapoints used in the steps below.
- uiTest – A complete web page for UI Test Target Tester which uses different types of structured datapoints.
- Read and understand how the "Simple Sensor Web Page Example (Web Page Template)" works before continuing.
- This example source code shows a simple web page for a FT 6050 EVB that can be used to create a custom web page.
- You will need to understand how to add datapoints and HTML objects.
- Read and understand the Simple Sensor web page documentation as it will help when developing your custom web page to this web page template.
Simple Sensor Web Page Example (Web Page Template) - Review the test section below (step 14) before starting as it will help you troubleshoot your code.
- Add at least one device to the SmartServer.
You will be changing or replacing the existing HTML and simplesensor.js source except if you are using the NcMultiSensor. In this case, you will add to the existing source code.- You can use an FT 6050 EVB with NcMultiSensor application.
- The provided source code will work without changes if the device name is Sensor1.
Create this Web page
- The provided source code will work without changes if the device name is Sensor1.
- Use one of your devices.
- It is best not to use a device that is currently being used on a production site.
- Use your SmartServer internal app.
- Use the UI Test Target Internal App – used if you do not have any devices, or just need something to experiment with.
Create this Web page - You will be creating a web page for a small subset of the UI Test Target Internal App datapoints.
Follow the instructions in the "Summary of Steps" below describing how to add the internal app.
- Use the UI Test Target Internal App – used if you do not have any devices, or just need something to experiment with.
- You can use an FT 6050 EVB with NcMultiSensor application.
- Determine which datapoints you want to monitor and control.
- Find your two datapoints and write down the path.
- For UI Test Target Internal App, find the datapoint path for "nviLampSw" and "nvoLampFb".
- For FT 6050 NcMultiSensor, find the datapoint path for second Lamp input and output.
- For your device, see if you have a input and output datapoint that you can control.
- Go to the CMS Datapoint Browser widget and find the datapoints for your web page.
- You will need to use at least one input and one output datapoint. Input datapoints are read/write and output datapoints are read-only.
You can still go through this example if you only have one datapoint.- The datapoint path uses the following format:
Datapoint path = <Device path>/<Block name>/<Block Index>/<Datapoint name>- For the screen capture above, the datapoint path is
ssi_1u60852 1.Subsystem 1.Device1/Switch/1/nvoValue - In an IMM network, the device path has the following format:
- device path = <subsystem path>/<device name>
- <subsystem path> can have multiple subsystems separated by "."
- In the example above, the <subsystem path> = "ssi_1u60852 1.Subsystem 1"
- For example: datapoint path = "ssi_1u60852 1.Subsystem 1/Device1/Switch/1/nvoValue"
- For DMM, the device path = <device name>
- For example: datapoint path = "Device1/Switch/1/nvoValue"
- For the screen capture above, the datapoint path is
- The datapoint value shows "state:0,value:0" indicating this is a structured datapoint.
- A scalar (non-structured datapoint) would show up as a single value like "0".
- In most cases your web page will show a scalar value or a field of a structured datapoint.
- For a structured SNVT_switch with two fields you would typically show each field separately, instead of the complete field.
- For a structured SNVT_switch with two fields you would typically show each field separately, instead of the complete field.
- The datapoint path uses the following format:
- Setup datapoint monitoring with a DLA file or with the CMS Datapoint Properties widget.
- The SmartServer only shows datapoints updates if you have:
- IMM – polling enabled.
- DMM – polling or event-driven updates enabled.
- For the purpose of testing web pages when using polled datapoints, you will want to set the polled rate to 1 or 2 seconds.
- Ensure that the logging rate is not less than 1 minute.
- Keep total poll rate (all datapoints, and polling on LonTalk, events, Modbus) need to be 5 polls per second or less.
- For UI Test Target – the DTP file that you imported earlier already included the poll rates. This step can be skipped.
- The SmartServer only shows datapoints updates if you have:
- Change the default Login Prompt.
- Create login.html: SFTP to /var/apollo/www/user and rename login1.html to login.html
- Create LoginLog.png: SFTP to /var/apollo/www/images and rename LoginLog1.png to LoginLog.png
- Unzip the Simple Demo Web Page and SFTP the Simple Sensor Web files to /var/apollo/www/user/test.
- Create a test directory so you have /var/apollo/www/user/test.
- Unzip Simple Demo Web Page.
- SFTP the following to /var/apollo/www/user/test.
- simplesensor.html
- css and scripts folders
- Only for FT6050 with NcMultiSensor App – try testing the provided web page.
- Enter the following URL into your web browser.
- /var/apollo/www/user/test
- You should see changes in the lux sensor when you put your hand over the EVB lux sensor.
- Change the SW in value and click the write button.
- If you have monitoring enabled, you will see changes within 5 seconds.
- Enter the following URL into your web browser.
- Edit simplesensor.html for your datapoints.
- Change the title.
- Add two HTML elements to your HTML body. Note the "id" must be unique for each HTML element.
- It is helpful if your HTML element "id" uses some portion of the datapoint path.
- If the HTML element shows the entire datapoint value, use the datapoint path as the "id".
For example:- "Device1/Switch/0/nviValueFb"
- If the HTML element is used to show one of the datapoint fields then you may want to add the field name to the end of the datapoint.
For example:- "Device1/Switch/0/nviValueFb/value"
- If two HTML elements for the same datapoint field are used, then you need to make sure they are unique.
For example: - "Device1/Switch/0/nviValueFb/value"
- "Device1/Switch/0/nviValueFb/value1"
- If the HTML element shows the entire datapoint value, use the datapoint path as the "id".
- For this tutorial you will add HTML elements for input and output datapoints, and a button to write the input datapoint to the end device.
Sample HTML elements for scalar datapoints:
Sample HTML elements for structured datapoints:
- Add the elements for each example.
- For UI Test Target Internal App, you will be showing two fields for each SNVT_switch datapoint:
- Write data using an input element. For example, change the "id" below to match your datapoints.
<input id="Device1/Switch/0/nviValueFb/value"> - Add a read datapoint using a span element.
<span id="Device1/Switch/0/nvoValue/value">
- Write data using an input element. For example, change the "id" below to match your datapoints.
- For an FT 6050 EVB:
- Provide two input HTML elements for the following datapoint so you can write data to an external device.
Each field should be placed in its own <input> field.
Lamp/1/nviValueFb - Add a button to write the value that you changed.
- Provide two input HTML elements for the following datapoint so you can display data stored in the external device.
Each field should be placed in its own <span> field.
Lamp/1/nvoValue
- Provide two input HTML elements for the following datapoint so you can write data to an external device.
- For your device:
- Write data using an input element. For example, change the "id" below to match your datapoints.
<input id="id1"> - Add a read datapoint using a span element.
<span id="id2">
- Write data using an input element. For example, change the "id" below to match your datapoints.
- For UI Test Target Internal App, you will be showing two fields for each SNVT_switch datapoint:
- It is helpful if your HTML element "id" uses some portion of the datapoint path.
- Add a button which will be used to change the value on the end device.
- Remove all other HTML elements if you are not using an FT 6050 EVB NcMultiSensor device.
- Edit simplesensor.js for your datapoint to read and write datapoint values.
- Each web page needs a unique web page tag that is used for reading datapoint values.
- Change the value of g_sWebpageTag to a new tag using the following format: "<company 3 character initials>_<Webpagename>=1"
- For example g_sWebpageTage="gle_controller=1"
- You will need to change the init1() function to add the datapoints and HTML elements to g_dpList array and any write functions you may need.
- You will need to add the following HTML elements:
- For structured datapoints, you should add a separate input and span for each field.
- For scalar datapoints, you only need to use a single input and single span for each datapoint.
Sample code to be added:
Structured datapoints:
Scalar datapoints:- For UI Test Target Internal App only:
You will be reading and writing structured datapoints. Both the "nviLampSw" and "nvoLampFb" are SNVT_switch, which means that the datapoint value has "state" and "value" fields.
For example: nviLampSw.value = {"state":1,"value":75}
You need to add the following:Two input HTML elements for nviLampSw1, one for state and one for value.
- Two span HTML elements for nvoLampFb.
- For all other devices or apps: add g_dpList object for each datapoint and a displayElement for the HTML elements on your web page.
This is for the FT 6050 EVB NcMultiSensor, so for other devices or internal apps, change the code to use your datapoint paths.
You need to add the following:- Keep the current init1() and HTML code but at new elements for Lamp/1.
For your device, find input or output datapoints that you can use for the web page.
- For UI Test Target Internal App only:
- Change the dpName and id to match the HTML elements you added in the previous step.
- Change g_sWebpageTag to a unique name.
- Remove all other g_dpList items if you are not using an FT 6050 EVB NcMultiSensor device.
- For FT 6050, you will use the existing source code and add to it.
- Change the write function as needed.
- Change or remove the validation function.
- Each web page needs a unique web page tag that is used for reading datapoint values.
- Add an image swapper.
- Find a datapoint for your image swapper and write down the path. For this tutorial you will use an output datapoint.
- For UI Test Target App, find the datapoint path for "nvoLampFb".
- For FT 6050 NcMultiSensor,find the datapoint path for "nvoLampFb".
- For your device, see if you have a input and output datapoint that you can control.
- You may want to use your own image files.
- You will need to change the lampImageSwapper function to work with your datapoints.
Use the following source code in your files (you will need to change the datapoint names and ids).
Image Swapper Source Code<img id="id1" src="switchTradGreenOn.gif" style="height:25px;width:25px"> <img src="switchTradOff.gif" style="display:none"> dpObj = new dpObject("inputdatapoint",true); dpObj = addDisplayElementToDpObject(dpObj, "Controller1/Lamp/1/nvoValueFb/state_2", "state", "r", "function", lampImageSwapper); g_dpList.push(dpObj); //****************************************************************** // lampImageSwapper // displayId - this is the HTML element id // dpName - this is the datapoint path name e.g., device1/block/0/nvoValue // value - value used for image swapper. This is the full datapoint value or a datapoint field value //****************************************************************** function lampImageSwapper(displayId, dpName, value) { var src; try { if((displayId == null) || (dpName == null) ||(value ==null)) return; if((displayId == "") || (dpName == "") ||(value == "")) return; if(typeof value === "string"){ value = Number(value); } var src = "switchTradOff.gif"; if(value === 1) src = "switchTradGreenOn.gif"; if(!document.getElementById(displayId).src.endsWith(src)) document.getElementById(displayId).src = src; } catch(e){} } }
- Find a datapoint for your image swapper and write down the path. For this tutorial you will use an output datapoint.
- Make an image swapper clickable.
- This example takes your existing image swapper and makes it clickable.
- You will be adding an onclick event to one of your <img> elements and which calls a function that will write a new value to an input datapoint.
- Find an input datapoint that corresponds to the output datapoint you used in the previous section.
- For UI Test Target Internal App, you will use "nvoLampFb" as the output datapoint and "nviLamp" as the input value.
- For FT 6050 NcMultiSensor, find the datapoint path for second Lamp input and output.
- For your device, see if you have a input datapoint that you can control for the image swapper you created in the previous step.
- You will need to add an onclick event to the <img> element that you assigned an id to.
- Add an onclick function to your <img> with an id, change id and inputdatapoint to match your HTML element and datapoint name.
onclick="imageStateClicked(this,'Controller1/Lamp/0/nviValue')"
<img id="id1" onclick="imageStateClicked(this,'inputdatapoint')" src="switchTradGreenOn.gif" style="height:25px;width:25px">
- Add an onclick function to your <img> with an id, change id and inputdatapoint to match your HTML element and datapoint name.
- Add a function for the onclick event and use an input function to change the value
- imageStateClicked() is an example of an onclick event that you can use.
Use the following source code in your files (you will need to change the datapoint names and ids).
Image Swapper onClick Function Source Code//****************************************************************** // imageStateClicked() // SNVT_switch value has two fields: state and value; this function only changes state // // displayObject - HMTL element object, this is usually using an output datapoint, though it can be an input datapoint // writeDpName - this is an input datapoint; //****************************************************************** function imageStateClicked(displayObject, writeDpName) { var displayId = displayObject.id; var iIndex = -1;//DP index in g_dpList var value; var json; var dpInfo; try { dpInfo = currentDpValueById(displayId); // output if(dpInfo != null){ if((dpInfo.dpName != "") && (dpInfo.value != "") && (dpInfo.value != "")) { value = dpInfo.value; iIndex = dpInfo.index; json = JSON.parse(value); // toggle state between 0 and 1 if(document.getElementById(displayId).src.endsWith("switchTradGreenOn.gif")) { json.state = 0; document.getElementById(displayId).src = "switchTradOff.gif"; } else { json.state = 1; document.getElementById(displayId).src = "switchTradGreenOn.gif"; } value = JSON.stringify(json); requestWriteData(writeDpName, value); // updates all other HTML elements using this datapoint and writes the value to the end device } } } catch(e) {} }
- This example takes your existing image swapper and makes it clickable.
- Add a jsFunction that gets called when one or more datapoint values change (e.g.; summing datapoints).
- Find two datapoints in which you can sum the values.
- For UI Test Target Internal App, you will use "nvoLampFb" and "nviLamp".
- For FT 6050 NcMultiSensor, you will sum the nvoValueFb of both block 1 and block 2.
- For your device, determine if you have two datapoints that you can sum.
- The sumValueField() function below sums the value field for a SNVT Switch.
To sum the value of the two scalar values make the following change:
Change sumValueField() the jsFunction source code below by changing the "// change this code if using scalars datapoints" section of the code.
Use the following source code in your files (you will need to change the datapoint names and ids).
jsFunction Source Code<span id="sum"> jsFunctionDpList = []; dpObj = new dpObject("datapoint1",true); jsFunctionDpList.push(dpObj); dpObj = new dpObject("datapoint2",true); jsFunctionDpList.push(dpObj); addJavascriptFunctionTojsFunctionObject(null, "sum", jsFunctionDpList, sumValueField); //****************************************************************** // sumValueField() // // This function sums the value field of one or more datapoints // // This jsfunction is called whenever the value or field value of at least one datapoint changes. // // parameter: user defined paramter list used by your Function - can be a string, number, object or array // displayId: used to associate a html element (like span) to the jsFunction. // dpList: lists datapoint Pathnames //****************************************************************** function sum(parameters, displayId, dpList) { var i; var json; var bValid = true; var sum = 0; if(dpList == null) return; try { // This example only cares about values for(i = 0; i < dpList.length; i ++) { try { valueStr = dpList[i].value; // full data point value if(valueStr == "") { bValid = false; break; } else { // change this code if using scalars datapoints json = JSON.parse(valueStr); value = json.value; // SNVT_switch value field sum += value; } } catch (err) {} } if(bValid) { document.getElementById(displayId).innerHTML = sum; } } catch (err) {} }
- Find two datapoints in which you can sum the values.
- Testing.
- Make sure web development tool does not show any formatting issues like missing "}".
- Access the new web page for example /user/apollo/www/user/test/test.html.
- Refresh the web page using Ctrl-F5 after making any changes to your web browser.
- You may need to delete the temporary internet files, exit the web browser, or even reboot the computer to see some changes.
- Check the web browser console to see if any errors. The console will show what line in the file is wrong.
- If the web page does not show datapoint values within 15 seconds (should be a lot faster), then there is probably an issue with your web page.
- Use the web browser debugger to debug your web page.
- Firefox - Click Menu > Web Developer > Debugger
- Look at "Network" to see network traffic.
- Debugger to step through your code.
- Console to see if there are HTML element issues.
- Chrome – Click Menu > More Tools > Developer Tools.
- Firefox - Click Menu > Web Developer > Debugger
- Make sure all datapoints in the g_dpList are unique, are datapoint pathname, and that all displayElement HTML ids are unique.
- If everything is working correctly, you should be able to write to a datapoint and see the output change within 10 seconds.
- See Web Page Troubleshooting for additional troubleshooting tips.
- Change the SmartServer home.
- Rename home1.html to home.html.
- /var/apollo/www/user/home.html
- /var/apollo/www/user/home.html
- Rename home1.html to home.html.
- Change the SmartServer home page to point to your test/simplesensor.html.
- Edit home.html and change the custom web page button to go to test/simplesensor.html.
- Edit home.html and change the custom web page button to go to test/simplesensor.html.