cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
13021
Views
50
Helpful
39
Replies

Uploading TelePresence macros or startup scripts via API

seanscott83
Level 1
Level 1

The idea of macros in CE 9.2 is great, and I've already configured a few test macros that add some helpful functionality for end users. My issue is over 50 of our ~150 endpoints is an SX10 and it's hard to add functionality to some devices but not all as the big sell when we migrated from Polycom to Cisco was "the same UI no matter what room you're in."

 

The idea of the ability to receive user feedback directly from the Touch 10 is something I've wished we could implement for a while. After some useful reading on this thread, it looks like you can actually use the new UI elements like text boxes, and have the remote feedback server listen for events. For example:

 

  1. Devices is registered to HTTP feedback server
  2. Device call status changes from in call to not in call and sends feedback to HTTP server
  3. HTTP server sends xCommand UserInterface Message TextInput Display"and records the feedback in a way we can parse.

I think we could do almost anything else you'd use macros for but do the automation on the webserver side since I already did this in CE 8 to automatically swap the content location during a call.

 

My issue now is trying to figure out how to automate the process of getting these onto the endpoints. To automatically register with a feedback server, you need to have a startup script, but according to the API documentation, you can only do so via the GUI, which is a pain to manually do on 150+ devices. Similarly, is there a way to upload and enable macros on the endpoints? It would be a nightmare if every time you wanted to add/remove/update a script, you had to manually log into the web GUI of every device.

 

Thoughts?

 

Thanks,

Sean

1 Accepted Solution

Accepted Solutions

Hi, change the expression to start with /event/ not /status/ on the widget one. Did that help?

/Magnus

View solution in original post

39 Replies 39

Patrick Sparkman
VIP Alumni
VIP Alumni

Maros are supported on any endpoint that can run CE9.2.1, except the SX10 due to platform stability issues, it's mentioned in the CE9 Release Notes.  For the endpoints that support macros, you can upload them using multiline commands via the API, see xCommand Macros in the API guides.

I understand that the SX10 doesn't support them, but when my deployment of ~150 SX endpoints has 50+ SX10s, it's hard to deploy a fragmented user experience. I'm mostly trying to see if I can replicate macro functionality by combining the new UI options and a HTTP feedback server. In order to do so I'd need to register a feedback server on boot and I don't see a way to upload startup scripts via the XML API.

 

Thanks for the tip on uploading Macros via the xAPI framework. Any chance you know the proper way to execute multi-line commands via the xAPI over XML? The REST API is so much more efficient than SSHing into individual endpoints and I've been looking to upload certs and branding images via HTTP and I can't find anything in the documentation about multi-line commands. I have a TAC case open about how to do it and they haven't been able to give me an answer for two weeks.  

 

Best,
Sean

Hi,

 

I can explain the functionality around the multiline commands and how to set these on remote systems with a script using a CSV file of IP addresses. The plan is to make it easier in the future to make a package that defines the endpoint configuration (containing macros, certificates, configurations, branding images etc) and then provision this using TMS or CUCM. How it will look like in the end I am not sure. But for now we need to do it the hard way. The API’s are available to be ready for the new provisioning solution but we can use them today with 9.2.1+ if you just know how. I will write something up later tonight. 

 

/M

Hi

I promised I would jump in with a few pointers on this.

There is a few commands that have the "Multiline" functionality in the xAPI. Let's take the Sign-in banner as an example:

xCommand SystemUnit SignInBanner Set
This is a signinbanner
This is line 2
This is line 3
.
OK
*r SignInBannerSetResult (status=OK):
** end

First you type the command and hit <enter>. You are now in Multiline mode where a linebreak will just take more input. This makes sense for the SignInBanner since you might have a lot of text you want to put in with multiple lines of text.

 

When you are done typing you end the input with a . and hit <enter> to execute the command.

The same concept is when uploading certificates or macros via the xAPI. You can copy paste all the macro code in after you enter multiline mode and at the end, hit <enter> type . and hit <enter> to execute.

 

xCommand Macros Macro Save Name: Test Overwrite: True
const xapi = require('xapi');
//Enables H323
function enableH323() {
    xapi.config.set('NetworkServices H323 Mode', 'On');
}
//Status listener for changes in the xStatus H323 Mode Status, if this changes to Disabled, flip back to enabled.
xapi.status.on('H323 Mode Status', value => {
    if (value == "Disabled") enableH323();
});

enableH323();
.

OK
*r MacroSaveResult (status=OK):
** end

The same multiline functionality exists with the certificate uploads, and also for branding images (base64 encoded images) where you just paste the base64 value of the image into the xAPI running the correct command of course.


This is simple enough for one endpoint, but what if you want to utilize the XMLAPI to distribute the functionality across endpoints?

 

I figure you already know how to utilize the XMLAPI using a programming language of your preference (I have a working example using PHP and I can provide this if it is a demand for it. But here is what the payloads would look like:

 

$macroContent = file_get_contents("example_macro.js");
$configPayload = " <XmlDoc> <Configuration> <Macros> <Mode>On</Mode> </Macros> </Configuration> </XmlDoc>"; $commandPayload = " <XmlDoc> <Command> <Macros> <Macro> <Save> <Name>example_macro</Name> <Overwrite>False</Overwrite> <body>".$macroContent."</body> </Save> <Activate> <Name>example_macro</Name> </Activate> </Macro> </Macros> </Command> </XmlDoc>";

The clue for setting multiline payloads via the XMLAPI is to set them into a <body></body> tag. The <body> tag is CASE SENSITIVE. If you use <Body> it will not work. Just a little heads up there.

The config payload (you need to separate the config and command payloads as they cannot be sent in the same payload) enables the Macro framework which is disabled by default (this is a logical first step). Then the command payload will upload the macro content using the multiline XMLAPI (you should extract the macro file contents into a variable as this looks better than writing the Macro as is into the script it self:S) and I also put in the command to make the uploaded macro active so you wont have to enable it manually, then it would all be kind of pointless...

 

You should also set a timer after activating the macro framework using the config payload (I figured 6 seconds was fine just to be sure) before uploading the macro and activating it with the command payload.

 

I hope this was somewhat helpful. Let me know if you have any questions.

 

/Magnus

 

Hi,

can you elaborate a bit on the contents of the <body></body>, please? I'm trying to send a UserInterface Extensions Set command in a similar manner and I'm just getting a 'Failed to parse xml' error from the codec. Inside the body tag I have this:

<Extensions>
<Version>1.4</Version>
<Panel>
<Icon>Language</Icon>
<Type>Statusbar</Type>
<Page>
<Name>Test panel</Name>
<Row>
<Name>Row 1</Name>
</Row>
<Row>
<Name>Row 2</Name>
</Row>
<Options/>
</Page>
<Name>Panel</Name>
</Panel>

</Extensions>

 

If I enter this on the CLI as a multiline command, it works without problems.

 

Thanks

 

 

Hi,

Sigh...

 

Yes, I see the problem. Putting XML (without XML encoding it) directly into the <body></body> will break the request as you end up in a situation of nested XML. You are trying to send an XML blob within a XML document as a string which is causing a lot of the input to truncate.

You need to XML encode the body content (actually, everything that goes into the putxml should be XML encoded, but we don´t get a lot of issues with it). The content should look like this:

 

&lt;Extensions&gt;
&lt;Version&gt;1.4&lt;/Version&gt;
&lt;Panel&gt;
&lt;Icon&gt;Language&lt;/Icon&gt;
&lt;Type&gt;Statusbar&lt;/Type&gt;
&lt;Page&gt;
&lt;Name&gt;Test panel&lt;/Name&gt;
&lt;Row&gt;
&lt;Name&gt;Row 1&lt;/Name&gt;
&lt;/Row&gt;
&lt;Row&gt;
&lt;Name&gt;Row 2&lt;/Name&gt;
&lt;/Row&gt;
&lt;Options/&gt;
&lt;/Page&gt;
&lt;Name&gt;Panel&lt;/Name&gt;
&lt;/Panel&gt;
&lt;/Extensions&gt;

I use a function in my script like this:

$xmlContent = htmlspecialchars(file_get_contents("example_roomcontrol.xml"), ENT_XML1);

The ^ converts the payload into what you see ^ ^. Then it works.

<XmlDoc>
	<Command>
		<UserInterface>
			<Extensions>
				<Set>
					<ConfigId>2</ConfigId>
					<body>&lt;Extensions&gt;
&lt;Version&gt;1.4&lt;/Version&gt;
&lt;Panel&gt;
&lt;Icon&gt;Language&lt;/Icon&gt;
&lt;Type&gt;Statusbar&lt;/Type&gt;
&lt;Page&gt;
&lt;Name&gt;Test panel&lt;/Name&gt;
&lt;Row&gt;
&lt;Name&gt;Row 1&lt;/Name&gt;
&lt;/Row&gt;
&lt;Row&gt;
&lt;Name&gt;Row 2&lt;/Name&gt;
&lt;/Row&gt;
&lt;Options/&gt;
&lt;/Page&gt;
&lt;Name&gt;Panel&lt;/Name&gt;
&lt;/Panel&gt;
&lt;/Extensions&gt;</body>
				</Set>
			</Extensions>
		</UserInterface>
	</Command>
</XmlDoc>

Request START <?xml version="1.0"?> <Command><ExtensionsSetResult status="OK"/> </Command>

You find XML encoders online as well, just copy paste the XML and you get the XML encoded content. Hope this helps!

 

/Magnus

Thanks! This solved the problem.

Glad to hear it! :)
/M

Thanks for all the help here. I'm just getting back from the US holiday weekend, but will run through your examples and verify I can get them to work in Postman and then in the Python framework we currently use to manage the endpoints via the XMLAPI.

 

One last questions. So I can try to replicate the macro framework on the SX10 using a HTTP feedback listener via startup script, is there a way to push startup scripts via the XMLAPI or the regular xCommand over SSH?


Also, glad to hear about those future plans to bundle configs and manage them in CUCM!

Best,
Sean

Hi Sean,

I do not recommend using a startup script for registering the HTTP feedback. If the device lose the feedback address (if the service falls down and it cannot reach it anymore it will wipe the HTTPFeedback, the startup script won´t help you there as it only runs during boot. And no, you cannot push startup scripts to the endpoint using the API, the startup script is an old feature that has not changed much. So it would anyway be cumbersome to set up such a script and only work as long as your service is up.

 

You should rather implement a heartbeat function on your service that will push (register) the HTTP feedback service on the endpoints it expects communication with on regular intervals using the XMLAPI of the device. Taking TMS as an example, it does this every 30 minutes I think, and it has a manual way of doing it by pushing the management settings. This requires the endpoint to be reachable by your external service and not behind firewall. Or create a cron job that launches a separate script that will register the feedback service on the devices locally. I don´t see any other ways of making sure the feedback setup is kept intact.

 

Macros may be introduced on the SX10 in the future, there are some platform instabilities that needs to be solved first (no guarantees though).

 

/M

I was able to use the info regarding the the XMLAPI and get it working via Postman to upload branding and certs. The API reference should definitely include the info regarding the extra <body> element and the extra enters required when using the xCommand terminal interface.

 

Thanks for the idea about setting up a heartbeat for managing the HTTP feedback items. I'll set up a cron job that does just that.

 

image.png

Hi,

did you manage to upload the private key too? I can successfully upload the CA certs, but the endpoint cert upload is failing with "Failed to read private key". In the log I have this entry: 

XapiCmd ERROR: Services Add privatekey: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

So for me it looks as if the password or the key format would not be good, but the same key file and password is accepted if I try to upload them from the web interface. My command xml is the following:

<Command>
  <Security>
    <Certificates>
      <Services>
        <Add>
          <body>
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----
       </body>
      <PrivateKeyPassword>
[password]
      </PrivateKeyPassword>
     </Add>
    </Services>
   </Certificates>
 </Security>
</Command>
 
Is any special encoding required on the <body> or is it enough to copy&paste the contents of the key and cert files in PEM format?
 
Thanks

You need the add the cert as a combined type which has both items in a single string.

Thanks. And meanwhile I found out that you have to also make sure that there is no new line after the password. I.e. 

<PrivateKeyPassword>[Password]</PrivateKeyPassword> is the correct form, and not 
<PrivateKeyPassword>
[Password]
</PrivateKeyPassword>