Keyboard Shortcuts
Likes
Search
HTML5 development for iPad
So, I have a great client that employs a couple of developers for his business and has approached me about having them develop his personal ipad gui.? I don't even know enough to be dangerous at this point and am even more confused after talking with TB.? So here goes.
1.? If this is even feasible 2.? How is it deployed and matched up to simpl program. 3.? How exactly would it run on a ipad 4.? Will the system require a SW-MOBILITY subscription |
I'm not an expert on this topic, but I've done some poking around and would be happy to know if I'm right/wrong/stupid/other.
1. Yes. HTML5/CSS3 is for everyone. ?The plugin is freely available in VSCode, etc. 2. You can coordinate join numbers with the developers and just put a TSW-1060 in your code. ?Or you can use the contract editor, which is probably a topic for a new thread. 3. Crestron says an app for that is "coming soon" 4. Yes! $10/mo per processor license. HTH. Michael |
I'm very much not well versed in HTML5 interfaces myself either, but I think the process would be defining an XPanel 3.0 HTML5 touchpanel device in SIMPL (if you're using SIMPL), having the client's developers produce the interface in accordance with the HTML5 guidelines at using VSCode (and I would anticipate their having a lot of questions that you'll have to work together to figure out answers to), loading the compiled XPanel 3.0 project to the control processor and activating the SW-MOBILITY license, and then accessing the appropriate XPanel project URL via Safari on an iPad at least until a native app solution is available. But again, I haven't even played around with HTML5 enough yet myself.
-Stuart |
This is what I have been told.? If you wish to run Crestron One app or HTLM5 web, you will need the subscription based license on the processor.? SW-MOBILITY subscription linked to processor.?
Licensing Structure SW-MOBILITY licenses are applied on a per?control system basis, making it easy to determine how many licenses are needed across an enterprise. Each license is applied to a single control system that supports mobile room control via the Crestron One?app. Licenses must be renewed monthly and can be purchased with additional months up front or as needed. Each control system also provides an unlicensed 60-day trial period for the service. Is it me, or does this sound like it will be more of a PitA to manage then the license they used to force for 3rd party lighting.? |
I have finally successful created a html5 interface to Crestron using a Raspberry Pi as the web server.? I am hoping to post a demo project soon showing how to do it.
I spent many hours getting this to work.? Starting with absolutely no web experience, trying to figure out what web technologies to use was the most challenging part.? And then there was a 1000 puzzles to solve to get it to work with my iPad, Android phone, and various web browsers (Firefox, Chrome, and Safari).? It will sense button presses and releases and will even accept several simultaneous button presses at the same time.? With a little bit of css magic, it displays properly on all on my devices. In the end I was able to do it with node.js as the backend server on the Pi and plain vanilla javascript, html, and css for the front end.? It uses websocket to give fast real time feedback and I have tested it with 20 clients accessing the server simultaneously and it has never crashed.? And it even works with a Series 2 Crestron processor. More to follow. Steve |
Phil Millross
¿ªÔÆÌåÓý@SteveKuehn!?Amazing, would love to see more info on this or maybe even a YouTube video of the setup!? On 31 Dec 2020, at 04:19, Steve Kuehn <steve@...> wrote:
|
You don¡¯t need to use or stay with the Crestron built solution. You can write HTML5 using any framework, and connect to the processor using websockets. The webpages can reside and be served my the controller.
CCI has a free websocket server module, or a premium which allows SSL and multi-connections. ENJOY! |
The Crestron One App is not the HTML5 app. The Crestron One is for the Crestron ?touchless¡° or better use your own mobile to control a TSW Panel control room solution.? I am pretty shure there is no need for a license using HTML5, OK we will need to buy the new HTML5 Control App. At the moment the demo version is named ?Crestron HTML5 Interface¡° or ?Crestron CH5¡°.? |
From: Programming for HTML Web XPanel uses the same Crestron HTML5 User Interface scripts and components with the addition of the required HTML Web XPanel library and configuration. Use of the HTML Web XPanel feature requires purchase of a software mobility license (SW?MOBILITY) per control system. On Thu, Dec 31, 2020, 2:42 PM stefan.mehre <stefan.mehre@...> wrote:
|
Crestron One App is?a HTML5 app.? Make sure you have the latest version; older versions didn't have the HTML5 option.? Inside the app you have to choose to use it as HTML5.? There is another thread on groups on how to setup a basic HTML5 project with SIMPL and Visual Studio Code.? I have done it and it works.? If you have zero web development skill the learning curve will be high.? The nice thing about this demo is it will get you started with a working demo to see how it works.? Crestron has a demo on their site that is much more complicated to understand but has more features.??
|
There is also a follow up video and using a simple UDP socket to talk to other programs or devices.? In that video I demo about how to use Node JS as a front end web server for a Python program.? .? But in reality, it was base on a program I wrote to do an HTML5 web interface for my Crestron MP2E processor using 15+ year old Crestron software back when Crestron's licensing terms were very simple.? All you need to do is write a very simple SIMPL+ JSON processor connected it to a SIMPL UDP socket to interface to the Raspberry Pi.? Below is the SIMPL+ code I used to do that. /* ? SIMPL+ Module Information ? (Fill in comments below) /* ? Compiler Directives */ #DEFINE_CONSTANT??? TOTALDIGITALS??? ??? 100 #DEFINE_CONSTANT??? TOTALANALOGS??? ??? 10 #DEFINE_CONSTANT??? TOTALSERIALS??? ??? 10 #DEFINE_CONSTANT Quote "\x22" #DEFINE_CONSTANT Backslash "\x5C" #DEFINE_CONSTANT LF "\x0A" #DEFINE_CONSTANT CR "\x0D" #DEFINE_CONSTANT Tab "\x09" #DEFINE_CONSTANT FF "\x0C" #DEFINE_CONSTANT Backspace "\x08" //#CATEGORY "0" #DEFAULT_VOLATILE // #PRINT_TO_TRACE // #DIGITAL_EXPAND // #ANALOG_SERIAL_EXPAND // #OUTPUT_SHIFT // #HELP_PDF_FILE "" // #DEFAULT_NONVOLATILE #ENABLE_STACK_CHECKING //#ENABLE_TRACE #HELP_BEGIN This program follows the GPL3 License: ??? This program is free software: you can redistribute it and/or modify ??? it under the terms of the GNU General Public License as published by ??? the Free Software Foundation, either version 3 of the License, or ??? (at your option) any later version. ??? This program is distributed in the hope that it will be useful, ??? but WITHOUT ANY WARRANTY; without even the implied warranty of ??? MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.? See the ??? GNU General Public License for more details. ??? You should have received a copy of the GNU General Public License ??? along with this program.? If not, see <https://www.gnu.org/licenses/>. Summary: ?? This module will only decode single JSON key:value pairs. ?? If will not decode more complicated multiple layer key:value pairs. ?? Module automatically adds/deletes escape sequences to/from JSON strings. INPUTS: ?? ?Debug??? D??? Enables debug info to be printed to the console. ?? ?Refresh??? D??? Resend all non-zero Digital, Analog, and Serial inputs to ?? ???? ??? ??? the webserver via the JSON_TX$ output. #HELP_END ????????????????????? ? DIGITAL_INPUT ?? ?Debug, ?? ?Refresh, ?? ?_SKIP_, ?? ?Dig_In[TOTALDIGITALS]; BUFFER_INPUT ?? ?_SKIP_, ?? ?JSON_RX$[2000]; ?? ? ANALOG_INPUT ?? ?_SKIP_, ?? ?Ana_In[TOTALANALOGS]; ?? ? STRING_INPUT ?? ?_SKIP_, ?? ?Ser_In$[TOTALSERIALS][256]; DIGITAL_OUTPUT ?? ?_SKIP_, ?? ?NewClient, ?? ?_SKIP_, ?? ?DigOut[TOTALDIGITALS]; STRING_OUTPUT ?? ?_SKIP_, ?? ?JSON_TX$; ?? ? ?? ? ANALOG_OUTPUT ?? ?_SKIP_, ?? ?AnaOut[TOTALANALOGS]; ?? ? STRING_OUTPUT ?? ?_SKIP_, ?? ?SerOut$[TOTALSERIALS]; INTEGER ?? ?LastDigPress, ?? ?Semaphore; STRING ??? SerialStorage$[TOTALSERIALS][256]; CHANGE JSON_RX$ ???? {??? ?? ?INTEGER Value, Index; ?? ?STRING JSON_PAIR$[512]; ?? ?STRING JSON_KEY$[512]; ?? ?STRING JSON_VALUE$[512]; ?? ?STRING JSON_TRASH[512]; ?????????? ? ??? if(Semaphore = 0) ?? ???? { ?? ???? Semaphore = 1; ?? ???? if (Debug) print("processing\n"); ?? ???? while(find("}", JSON_RX$) > 0) ?? ???? ??? { ?? ???? ??? JSON_PAIR$ = remove("}", JSON_RX$); ?? ???? ??? Index = find("{", JSON_PAIR$); ?? ???? ??? if(Index > 0) ?? ???? ??? ??? { ?? ???? ??? ??? JSON_PAIR$ = mid(JSON_PAIR$,Index,len(JSON_PAIR$)); ?? ???? ??? ??? if (Debug) print("JSON_PAIR$=%s\n",JSON_PAIR$); ?? ???? ??? ??? JSON_VALUE$ = JSON_PAIR$; ?? ???? ??? ??? // Find JSON Key ?? ???? ??? ??? JSON_KEY$ = remove(":", JSON_VALUE$);??? ??? ??? ??? ?? ???? ??? ??? JSON_TRASH = remove(Quote, JSON_KEY$); ?? ???? ??? ??? JSON_KEY$ = remove(Quote, JSON_KEY$); ?? ???? ??? ??? Index = len(JSON_KEY$); ?? ???? ??? ??? if (Index>2) {JSON_KEY$ = left(JSON_KEY$, Index-1);} ?? ???? ??? ??? ??? ??? else {JSON_KEY$ = "";} ?? ???? ??? ??? if (Debug) print("JSON_KEY$=%s\n",JSON_KEY$); ?? ???? ??? ??? // Find JSON VALUE ?? ???? ??? ??? JSON_VALUE$ = left(JSON_VALUE$,len(JSON_VALUE$)-1); // remove trailing } ?? ???? ??? ??? if (Debug) print("JSON_VALUE$=%s\n",JSON_VALUE$); ??????????????? // Digital signal ?? ???? ??? ??? if (left(JSON_KEY$, 1) = "D") // this is a Digital signal ?? ???? ??? ??? ??? { ?? ???? ??? ??? ??? index = atoi(JSON_KEY$); ?? ???? ??? ??? ??? if ((Index) && (Index <= TOTALDIGITALS)) ?? ???? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? Value = atoi(JSON_VALUE$); ?? ???? ??? ??? ??? ??? switch (Value) ?? ???? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? case (0) : ?? ???? ??? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? ??? // Test if button is action. If not, release the last button ?? ???? ??? ??? ??? ??? ??? ??? // This is in class some slides off the button while holding it ?? ???? ??? ??? ??? ??? ??? ??? if (DigOut[Index]) DigOut[Index] = 0; ?? ???? ??? ??? ??? ??? ??? ??? else if(LastDigPress) DigOut[LastDigPress] = 0; ???? ??? ??? ??? ??? ??? ??? ??? LastDigPress = 0; ?? ???? ??? ??? ??? ??? ??? ??? } ?? ???? ??? ??? ??? ??? ??? case (1) : ?? ???? ??? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? ??? DigOut[Index] = 1; ?? ???? ??? ??? ??? ??? ??? ??? LastDigPress = Index; ?? ???? ??? ??? ??? ??? ??? ??? } ?? ???? ??? ??? ??? ??? ??? case (2) : ?? ???? ??? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? ??? DigOut[Index] = 1; ?? ???? ??? ??? ??? ??? ??? ??? processlogic(); ?? ???? ??? ??? ??? ??? ??? ??? DigOut[Index] = 0; ?? ???? ??? ??? ??? ??? ??? ??? } ?? ???? ??? ??? ??? ??? ??? } ?? ???? ??? ??? ??? ??? } ?? ???? ??? ??? ??? } ?? ???? ??? ??? // Analog Signal ?? ???? ??? ??? else if (left(JSON_KEY$, 1) = "A") // this is a Analog signal ?? ???? ??? ??? ??? { ?? ???? ??? ??? ??? index = atoi(JSON_KEY$); ?? ???? ??? ??? ??? if ( (Index) && (Index <= TOTALANALOGS) ) ?? ???? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? Value = atoi(JSON_VALUE$); ?? ???? ??? ??? ??? ??? AnaOut[Index] = atoi(JSON_VALUE$); ?? ???? ??? ??? ??? ??? } ?? ???? ??? ??? ??? } ?? ???? ??? ??? //Serial signal ?? ???? ??? ??? else if (left(JSON_KEY$, 1) = "S") // this is a Serial signal ?? ???? ??? ??? ??? { ?? ???? ??? ??? ??? index = atoi(JSON_KEY$); ?? ???? ??? ??? ??? if ( (Index) && (Index <= TOTALSERIALS) ) ?? ???? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? JSON_TRASH = remove(Quote, JSON_Value$); ?????????? ? ?? ???? ??? ??? ??? ??? // Convert Backspace escape sequences ?? ???? ??? ??? ??? ??? Value = find("\\b" , JSON_Value$); ?? ???? ??? ??? ??? ??? while (Value)??? ?? ???? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? JSON_Value$ = left(JSON_Value$,Value-1) + Backspace + right(JSON_Value$, len(JSON_Value$)- (Value+1) ); ?? ???? ??? ??? ??? ??? ??? Value = find("\\b", JSON_Value$, Value+2); ?? ???? ??? ??? ??? ??? ??? } ?? ???? ??? ??? ??? ??? // Convert FormFeed escape sequences ?? ???? ??? ??? ??? ??? Value = find("\\f" , JSON_Value$); ?? ???? ??? ??? ??? ??? while (Value)??? ?? ???? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? JSON_Value$ = left(JSON_Value$,Value-1) + FF + right(JSON_Value$, len(JSON_Value$)- (Value+1) ); ?? ???? ??? ??? ??? ??? ??? Value = find("\\f", JSON_Value$, Value+2); ?? ???? ??? ??? ??? ??? ??? } ??????????????????????? ? ?? ???? ??? ??? ??? ??? // Convert LineFeed escape sequences ?? ???? ??? ??? ??? ??? Value = find("\\n" , JSON_Value$); ?? ???? ??? ??? ??? ??? while (Value)??? ?? ???? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? JSON_Value$ = left(JSON_Value$,Value-1) + LF + right(JSON_Value$, len(JSON_Value$)- (Value+1) ); ?? ???? ??? ??? ??? ??? ??? Value = find("\\n", JSON_Value$, Value+2); ?? ???? ??? ??? ??? ??? ??? } ?? ???? ??? ??? ??? ??? // Convert Carriage Return escape sequences ?? ???? ??? ??? ??? ??? Value = find("\\r" , JSON_Value$); ?? ???? ??? ??? ??? ??? while (Value)??? ?? ???? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? JSON_Value$ = left(JSON_Value$,Value-1) + CR + right(JSON_Value$, len(JSON_Value$)-(Value+1) ); ?? ???? ??? ??? ??? ??? ??? Value = find("\\r", JSON_Value$, Value+2); ?? ???? ??? ??? ??? ??? ??? } ?????????????????????? ? ?? ???? ??? ??? ??? ??? // Convert Tab escape sequences ?? ???? ??? ??? ??? ??? Value = find("\\t" , JSON_Value$); ?? ???? ??? ??? ??? ??? while (Value)??? ?? ???? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? JSON_Value$ = left(JSON_Value$,Value-1) + Tab + right(JSON_Value$, len(JSON_Value$)- (Value+1) ); ?? ???? ??? ??? ??? ??? ??? Value = find("\\t", JSON_Value$, Value+2); ?? ???? ??? ??? ??? ??? ??? } ?? ???? ??? ??? ??? ??? // Convert Quote escape sequences to quote ?? ???? ??? ??? ??? ??? Value = find("\x5C22" , JSON_Value$); ?? ???? ??? ??? ??? ??? while (Value)??? ?? ???? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? JSON_Value$ = left(JSON_Value$,Value-1) + right(JSON_Value$, len(JSON_Value$)- Value); ?? ???? ??? ??? ??? ??? ??? Value = find("\x5C22", JSON_Value$, Value+2); ?? ???? ??? ??? ??? ??? ??? } ? ??? ??? ??? ??? ??? ??? // Convert Backslash escape sequences to Backslash ?? ???? ??? ??? ??? ??? Value = find("\x5C5C" , JSON_Value$); ?? ???? ??? ??? ??? ??? while (Value)??? ?? ???? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? JSON_Value$ = left(JSON_Value$,Value-1) + right(JSON_Value$, len(JSON_Value$)- Value); ?? ???? ??? ??? ??? ??? ??? Value = find("\x5C5C", JSON_Value$, Value+2); ?? ???? ??? ??? ??? ??? ??? } ?? ???? ??? ??? ??? ??? // find end of line ?? ???? ??? ??? ??? ??? Value = 0; ?? ???? ??? ??? ??? ??? while (find(Quote, JSON_Value$, Value)) ?? ???? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? Value = find(Quote, JSON_Value$, Value); ?? ???? ??? ??? ??? ??? ??? } ?? ???? ??? ??? ??? ??? // Removed trailing quote ?? ???? ??? ??? ??? ??? if (Value) JSON_Value$ = left(JSON_Value$, Value-1); ?? ???? ??? ??? ??? ??? if (len(JSON_Value$) > 2) ?? ???? ??? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? ??? JSON_Value$ = left(JSON_Value$, len(JSON_Value$)-1); ?? ???? ??? ??? ??? ??? ??? SerOut$[Index] = JSON_VALUE$; ?? ???? ??? ??? ??? ??? ??? } ?? ???? ??? ??? ??? ??? ?? ???? ??? ??? ??? ??? } ?? ???? ??? ??? ??? } ?? ???? ??? ??? else if (left(JSON_KEY$, 1) = "") // this is a null signal ?? ???? ??? ??? ??? { ?? ???? ??? ??? ??? // Release occurred over a non button area of screen.? Release previously pressed button ?? ???? ??? ??? ??? // in case this is the result of finger sliding off of button. ?? ???? ??? ??? ??? if ((LastDigPress) && (atoi(JSON_VALUE$) = 0) ) ?? ???? ??? ??? ??? ??? { ?? ???? ??? ??? ??? ??? DigOut[LastDigPress] = 0; ?? ???? ??? ??? ??? ??? LastDigPress = 0; ?? ???? ??? ??? ??? ??? } ?? ???? ??? ??? ??? } ?? ???? ??? ??? else if (find("NewClient",JSON_KEY$)) // A newClient ?? ???? ??? ??? ??? { ?? ???? ??? ??? ??? NewClient = 1; ?? ???? ??? ??? ??? processlogic(); ?? ???? ??? ??? ??? NewClient = 0; ?? ???? ??? ??? ??? } ?? ???? ??? ??? else if ((LastDigPress) && (JSON_VALUE$ = "0") ) ?? ???? ??? ??? ??? { ?? ???? ??? ??? ??? // Release occurred over a non button area of screen.? Release previously pressed button ?? ???? ??? ??? ??? // in case this is the result of finger sliding off of button. ?? ???? ??? ??? ??? DigOut[LastDigPress] = 0; ?? ???? ??? ??? ??? LastDigPress = 0; ?? ???? ??? ??? ??? } ?????????????? } ?? ???? ??? processlogic(); ?? ???? ??? } // End of while(find("}", JSON_RX$) > 0) ?? ???? Semaphore = 0; ?? ???? print("end process\n"); ?? ???? ?? ???? }? // End of if(Semaphore = 0) ?? ?} // End of CHANGE JSON_RX$ PUSH Refresh ?? ?{ ?? ?INTEGER ?? ???? Value, ?? ???? Index; ?? ?STRING TempStr$[255]; ?? ?for (Index = 1 to TOTALDIGITALS) ?? ???? { ?? ???? if (Dig_In[Index]) ?? ???? if ( (IsSignalDefined(Dig_In[Index])) && (Dig_In[Index]) ) ?? ???? ??? { ?? ???? ??? makestring(TempStr$,"%sD%u%s:1",Quote,Index,Quote); ?? ???? ??? TempStr$ = "{" + TempStr$ + "}"; // workaround for Series3 compiler problem with braces. ?? ???? ??? JSON_TX$ = TempStr$; ?? ???? ??? processlogic(); ?? ???? ??? } ?? ???? } ?? ?for (Index = 1 to TOTALANALOGS) ?? ???? { ?? ???? if ( (IsSignalDefined(Ana_In[Index])) && (Ana_In[Index]) ) ?? ???? ??? { ?? ???? ??? Value = Ana_In[Index]; ?? ???? ??? makestring(TempStr$,"%sA%u%s:%u",Quote,Index,Quote,Value); ?? ???? ??? TempStr$ = "{" + TempStr$ + "}"; // workaround for Series3 compiler problem with braces. ?? ???? ??? JSON_TX$ = TempStr$; ?? ???? ??? processlogic(); ?? ???? ??? } ?? ???? } ?? ?for (Index = 1 to TOTALSERIALS) ?? ???? { ?? ???? if ( (IsSignalDefined(Ser_In$[Index])) && (len(Ser_In$[Index]) )? ) ?? ???? ??? { ?? ???? ??? JSON_TX$ = SerialStorage$[Index]; ?? ???? ??? processlogic(); ?? ???? ??? } ?? ???? } ?? ?} CHANGE Dig_In??? ??? { ?? ?INTEGER Index; ?? ?STRING TempStr$[255]; ?? ? ?? ?Index = getlastmodifiedarrayindex(); ?? ?if (Dig_In[Index]) ?? ???? { ?? ???? makestring(TempStr$,"%sD%u%s:1",Quote,Index,Quote); ?? ???? } ?? ?else ?? ???? { ?? ???? makestring(TempStr$,"%sD%u%s:0",Quote,Index,Quote); ?? ???? } ?? ?TempStr$ = "{" + TempStr$ + "}"; // workaround for Series3 compiler problem with braces. ?? ?if (Debug) print("Sending JSON:%s\n",TempStr$); ?? ?JSON_TX$ = TempStr$; ?? ?processlogic(); ?? ?} ?? ? CHANGE Ana_In ?? ?{ ?? ?INTEGER ?? ???? Value, ?? ???? Index; ?? ?STRING TempStr$[255];??? ?? ?Index = getlastmodifiedarrayindex(); ?? ?Value = Ana_In[Index]; ?? ?makestring(TempStr$,"%sA%u%s:%u",Quote,Index,Quote,Value); ?? ?TempStr$ = "{" + TempStr$ + "}"; // workaround for Series3 compiler problem with braces. ?? ?if (Debug) print("Sending JSON:%s\n",TempStr$); ?? ?JSON_TX$ = TempStr$; ?? ?} ?? ? CHANGE Ser_In$ ?? ?{ ?? ?INTEGER ?? ???? Value, ?? ???? Index; ?? ?STRING TempStr$[255];??? ?? ? ?? ?Index = getlastmodifiedarrayindex(); ?? ?TempStr$ = Ser_In$[Index]; ?? ?// Replaced backslash with \\ ?? ?Value = find(Backslash ,TempStr$); ?? ?while (Value) ?? ???? { ?? ???? TempStr$ = left(TempStr$,Value-1) + Backslash + right(TempStr$, len(TempStr$) - (Value-1) ); ?? ???? Value = find(Quote,TempStr$, Value+2); ?? ???? } ? ?? ?// Replaced Quote with \" ?? ?Value = find(Quote,TempStr$); ?? ?while (Value) ?? ???? { ?? ???? TempStr$ = left(TempStr$,Value-1) + Backslash + right(TempStr$, len(TempStr$) - (Value-1) ); ?? ???? Value = find(Quote,TempStr$, Value+2); ?? ???? } ??? // Replaced LineFeed with \n" ?? ?Value = find(LF,TempStr$); ?? ?while (Value) ?? ???? { ?? ???? TempStr$ = left(TempStr$,Value-1) + "\\n" + right(TempStr$, len(TempStr$) - (Value) ); ?? ???? Value = find(LF,TempStr$, Value+2); ?? ???? } ? ? ?? ?// Replaced Carrage Return with \r" ?? ?Value = find(CR,TempStr$); ?? ?while (Value) ?? ???? { ?? ???? TempStr$ = left(TempStr$,Value-1) + "\\r" + right(TempStr$, len(TempStr$) - (Value) ); ?? ???? Value = find(CR,TempStr$, Value+2); ?? ???? } ?? ? ?? ?// Replaced Tab with \t" ?? ?Value = find(Tab,TempStr$); ?? ?while (Value) ?? ???? { ?? ???? TempStr$ = left(TempStr$,Value-1) + "\\t" + right(TempStr$, len(TempStr$) - (Value) ); ?? ???? Value = find(Tab,TempStr$, Value+2); ?? ???? } ?? ? ?? ?// Replaced FormFeed with \f" ?? ?Value = find(FF,TempStr$); ?? ?while (Value) ?? ???? { ?? ???? TempStr$ = left(TempStr$,Value-1) + "\\f" + right(TempStr$, len(TempStr$) - (Value) ); ?? ???? Value = find(FF,TempStr$, Value+2); ?? ???? } ?? ?makestring(TempStr$,"%sS%u%s:%s%s%s",Quote,Index,Quote,Quote,TempStr$,Quote); ?? ?TempStr$ = "{" + TempStr$ + "}"; // workaround for Series3 compiler problem with braces. ?? ?if (Debug) print("Sending JSON:%s\n",TempStr$); ?? ?JSON_TX$ = TempStr$; ?? ?SerialStorage$[Index] = TempStr$; ?? ?} ?? ? FUNCTION Main() ?? ?{ ?? ?INTEGER Index; ?? ?Semaphore = 0; ?? ?for (Index = 1 to TOTALSERIALS) ?? ???? { ?? ???? SerialStorage$[Index] =??? ""; ?? ???? } ?? ?if ( WaitForInitializationComplete() < 0 ) ??????? { ??????? print("Webserver_JSON_Processor: Error waiting for initialization complete\n"); ??????? return; ??????? } ?? ???? ?? ?} |
Hi everyone,?
Our experience at is that creating interfaces in HTML is a major undertaking. Here's a video of our interface running on the CrestronOne app?. Technically you can run it on a browser but at this point it's more for dev work. We are going to launch this as a product for other CSPs or Integrators to license. We've designed it so it runs hosted on a 4-Series processor and can communicate to any SIMPL program through an EIC. The idea is that anyone can export the signals to integrate to the HTML interface. We are also planning to offer design a front end dev. services if our Framework doesn't fit your needs.? If anyone is interested you can contact us through our website.? ? JJ Mancera |