Securifi Community Forum
Securifi Products => Almond+ => Topic started by: Ashok on January 05, 2016, 10:11:32 am
-
Please post any questions or feedback related to Web Socket API here.
-
Excellent, many thanks. ;D
Working with it now.
-
Small hint to play with it using Chrome.
Install Simple WebSocket extension. Works great.
https://chrome.google.com/webstore/detail/simple-websocket-client/pfdhoblngboilpfeibdedpjgfnlcodoo/related?hl=en
-
Small hint to play with it using Chrome.
Install Simple WebSocket extension. Works great.
https://chrome.google.com/webstore/detail/simple-websocket-client/pfdhoblngboilpfeibdedpjgfnlcodoo/related?hl=en
Yep, it does work nicely and it's simple for basic testing.
-
In Scenes section for Add/Remove/Update/Activate you have an mii of 324 and it is specified as a MobileInternalIndex instead of "mii".
Q: Should this also be a random key?
Q: Was this just a example that didn't have <random key> inserted?
-
Please post any questions or feedback related to Web Socket API here.
Thanks for releasing this.
FYI for connection/authentication, the 'user' (root) isn't necessary.
Both of these work:
<webinterfaceUrl>:<portid>/<Login>/<password>
<webinterfaceUrl>:<portid>/<password>
-
In Scenes section for Add/Remove/Update/Activate you have an mii of 324 and it is specified as a MobileInternalIndex instead of "mii".
Q: Should this also be a random key?
Q: Was this just a example that didn't have <random key> inserted?
mii and MobileInternalIndex appear to be interchangeable, but I've only cross-tested a few.
Yes, the key is any random number as discussed elsewhere, and the response just echos the supplied value. In that instance you mention, they could edit it to be consistent.
-
mii and MobileInternalIndex appear to be interchangeable, but I've only cross-tested a few.
Yes, the key is any random number as discussed elsewhere, and the response just echos the supplied value. In that instance you mention, they could edit it to be consistent.
Yep, same thing I found. Figured that was all it was but it's worth making the edit to be clear.
-
We really need to be able to use wss.
Secure Websockets are a 'must' not a 'nice to have'.
-
Either I found a bug or I'm doing it wrong.
I have a GE link multilevel bulb and am turning it off by:
{
"mii":"781",
"cmd":"setdeviceindex",
"devid":"2",
"index":"1",
"value":"false"
}
I get the following output
{"mii":"781","commandtype":"setdeviceindex","success":"true","data":{"devid":"2","index":"1","value":"false"}}
{"commandtype":"SensorUpdate","data":{"2":{"2":{"index":"2","name":"SWITCH BINARY","value":"false"}}}}
{"commandtype":"SensorUpdate","data":{"2":{"1":{"index":"1","name":"SWITCH MULTILEVEL","value":"0"}}}}
and the light turns off
Then I send:
{
"mii":"782",
"cmd":"setdeviceindex",
"devid":"2",
"index":"1",
"value":"true"
}
and get
{"mii":"782","commandtype":"setdeviceindex","success":"true","data":{"devid":"2","index":"1","value":"true"}}
and the light stays off.
I have to go into the app turn the dimmer up then the light will turn on but if I set dimmer up through the websocket nothing happens.
-
Hello and welcome to multilevel switches...and dim levels
Let me actually try your code and some of my own...will need a few minutes.
This is the output of using the Almond Android App to control a GELink Bulb and turning it On/Off
Notice the use of Index 2 and the SWITCH BINARY function call, you are calling Index 1 which is SWITCH MULTILEVEL.
{"commandtype":"SensorUpdate","data":{"22":{"2":{"index":"2","name":"SWITCH BINARY","value":"true"}}}}
{"commandtype":"SensorUpdate","data":{"22":{"2":{"index":"2","name":"SWITCH BINARY","value":"false"}}}}
-
@Zexon
throw the code brackets around your code, makes it easier to follow
That would be using the [ and ] around the word "code" to open and around "/code" to finish.
-
Your code is turning the Light off but it is setting the Dim Level to 0 to do so.
So even when it is turned back on, it will be at Dim Level 0, but you are not turning it on, you are resending Dim Level 0.
Change your value from "false" to "255" and watch what happens.
Your light should turn on and have a value of 100% Dim.
That's one of the things with multilevel switches, well light bulbs anyway, you can turn them on and off by setting Dim to 0 or on by setting Dim to something greater than 0.
-
Turn ON/OFF using the MultiLevel Class (index 1)
OFF
{
"mii":"781",
"cmd":"setdeviceindex",
"devid":"2",
"index":"1",
"value":"false"
}
OR
{
"mii":"781",
"cmd":"setdeviceindex",
"devid":"2",
"index":"1",
"value":"0"
}
TURN ON and DIM 100% (which means 100% brightness or dimmed to 100% brightness, max brightness, 0% Dim/Brightness would be Off)
{
"mii":"781",
"cmd":"setdeviceindex",
"devid":"2",
"index":"1",
"value":"255"
}
-
Now, if you want to use the SWITCH_BINARY controls of simply ON/OFF and leave the DIM Level unchanged, then you need to use the appropriate INDEX.
Take a look at the docs for more info
http://firmware.securifi.com/sdkdocs/index.html
ON
{
"mii":"781",
"cmd":"setdeviceindex",
"devid":"22",
"index":"2",
"value":"true"
}
OFF
{
"mii":"781",
"cmd":"setdeviceindex",
"devid":"22",
"index":"2",
"value":"false"
}
So you were almost there, you were simply using the wrong index. You were calling MultiLevel Switch Functionality and changing the Dim Level instead of calling Binary Switch commands and using the On/Off function with values of True / False.
-
I should also mention that in order for the apps to work correctly, or rather, be updated correctly every time, you should send both the SWITCH BINARY ON command when you send the SWITCH MULTILEVEL dim command for an ON/Brightness>0.
The same for OFF using Dim 0%, SWITCH BINARY FALSE if you are going to send it a SWITCH MULTILEVEL 0 command.
-
@SecureComp
Thank you I didn't notice that I had the wrong index. That's frustrating I fought with that for longer then I would like to admit...
-
@SecureComp
Thank you I didn't notice that I had the wrong index. That's frustrating I fought with that for longer then I would like to admit...
No worries, we've all been there.
-
I'm really interested by Jeedom a Home automation software.
Is the Web Socket API (will) allow to use Almond + in it ?
-
I should also mention that in order for the apps to work correctly, or rather, be updated correctly every time, you should send both the SWITCH BINARY ON command when you send the SWITCH MULTILEVEL dim command for an ON/Brightness>0.
The same for OFF using Dim 0%, SWITCH BINARY FALSE if you are going to send it a SWITCH MULTILEVEL 0 command.
This is true when setting up scenes in the apps as well.
-
I'm really interested by Jeedom a Home automation software.
Is the Web Socket API (will) allow to use Almond + in it ?
AFAIK nothing exists in Jeedom for Almond+ right now, but yes, you can use the WebSocket API to generate something that would allow it to work with Jeedom. Someone would have to develop the module to be in the Jeedom Market.
-
Hi!
It seems like there is only POST supported, GET would be also great because my HA Server i like to connect only supports GET requests.
Bye
-
@ Hyper,
Hi!
It seems like there is only POST supported, GET would be also great because my HA Server i like to connect only supports GET requests.
A bit more information on this would be helpful.
-
@ Hyper,
A bit more information on this would be helpful.
Sorry for my inadequate post.
My problem is, I need a communication to the almond per HTTP Get request. Therefore a simple webservice.
For changeing the almond mode or switching devices.
A websocket is in my usecase too much, because my HomeAutomation Server does not support WebSockets.
-
Authentication isn't working, as far as I can tell. With both the Chrome 'Simple WebSocket Client' and with node-red, I'm unable to get the websocket to connect using the username (root) and password that I use to connect to the router's web interface. Here's the URL I'm using (I've changed the password here, but my real one does include a $ character):
ws://10.0.1.1:7681/root/aL$dcb3Uqjka7Jd
I've logged into the Almond+ via ssh and am watching the messages go by in the webServer.log file in realtime via the "tail -f /tmp/webServer.log" command. When I try to connect a websocket using that URL, here's the message that appears in the log:
[2016-2-3 11:1:2.178937500] {INFO} passwd twirp and received password root/aL$dcb3Uqjka7Jd
[2016-2-3 11:1:2.179264580] {INFO} LWS_CALLBACK_ESTABLISHED wrong login password so connection closed
[2016-2-3 11:1:2.221481000] {INFO} LWS_CALLBACK_CLOSED
Ah, "twirp" again. Wasn't that the old websocket interface? I am running firmware AP2-R083-L009-W016-ZW016-ZB005, so I'd have expected to be using the new websocket URL to connect.
In any case, ws://10.0.1.1:7681/twirp allows me to open and maintain a websocket connection to the router. But ws://10.0.1.1:7681/user/pass does not.
-
try a shorter password
also
ws://10.0.1.1:7681/password where password=your password
-
Ah, I was worried that'd be the problem. I can make a less secure password, though it'd be good if the websocket accepts any password that can be used for the router's LuCI interface so people don't have to dumb-down their passwords to use the websocket.
Is the 'twirp' access going to go away in a future firmware update? It seems like a security risk. I haven't tried many commands yet, but it would seem that anyone with access to the local network may be able to take control of the router using 'twirp'.
-
Once someone is on your LAN, WiFi or Wired you have mega security risks period.
Post up if the password change solved the problem. I haven't tested mine to see what the max supported length or characters are.
-
First off, thanks for the websockets API. I've been developing an app against it, and it gets the job done (for the most part). That said, here's some unsorted feedback:
Security
I'll echo what has been mentioned a few times already in this thread: secure transport (wss://) is absolutely imperative. This is a worthwhile read: https://devcenter.heroku.com/articles/websocket-security. Also, including the username/pass in the URI is particularly bad since secure transport won't conceal this from passive network sniffing. It's the security equivalent of walking around with your most important password written on your forehead.
Consistency in naming conventions
Case inconsistencies:
- Command names — "createrule" vs "ClientList"
- Attributes in the return object — "CommandType" vs "commandtype", "DeviceID" vs "deviceid", "Name" vs. "name", etc.
Attribute name inconsistencies:
- In the response — "devid" vs "deviceid"
- In the request — "mii" vs "MobileInternalIndex" and "cmd" vs "CommandType"
I've started including the 32-char random key as both both "mii" and "MobileInternalIndex" attributes, which the protocol seems just fine with. However, if you supply both "cmd" and "CommandType" (even if they're the same), it works for some commands ("devicelist" for instance), while other commands (such as "DynamicSceneList") will return this: { "mii":"<random key>", "commandtype":"unknown" }
Incomplete documentation
This is somewhat expected seeing as the API is all shiny and new. It's cropped up mostly when I'm looking for a list of acceptable values for a particular parameter. For instance, I was trying to activate a specific rule, so I sent the following:
{
"mii":"<random key>",
"cmd":"validaterule",
"ruleid":"<ruleid>",
"value":"true"
}
Well, this didn't work. Turns out, the value attribute was expecting either a "1" or a "0" — even though the response data shows "true" or "false" (ex: "data":{"value":"true","ruleid":"<ruleid>").
Structural weirdness (possibly typos?)
Here's the sample request for ActivateScene:
{
"CommandType":"ActivateScene",
"MobileInternalIndex":"324",
"Scenes":{
"ID":"11"
}
}
Should the "Scenes" attribute be an array?
Thanks for reading! Oh, and who should I talk to about wiki edit rights for the documentation?
-
@ fort,
who should I talk to about wiki edit rights for the documentation?
Done. Could you please check and let me know, if you have any issues in editing the Wiki.
-
good stuff @fort
Seeing the same things, handling the case sensitivities isn't a big deal, just tedious.
Using the same solution and declaring two variables at times when really one should be enough. (mii)
Wondering whether the to send "true" "false" or 1, 0 has tripped me up a few times.
Fixing these items and a few others would speed up development just because I wouldn't be chasing down issues but I do understand the level of effort that would need to happen on Securifi's part as well.
-
@ fort,
Incomplete documentation
This is somewhat expected seeing as the API is all shiny and new. It's cropped up mostly when I'm looking for a list of acceptable values for a particular parameter. For instance, I was trying to activate a specific rule, so I sent the following:
{
"mii":"<random key>",
"cmd":"validaterule",
"ruleid":"<ruleid>",
"value":"true"
}
Well, this didn't work. Turns out, the value attribute was expecting either a "1" or a "0" — even though the response data shows "true" or "false" (ex: "data":{"value":"true","ruleid":"<ruleid>").
Yes, that is what the command expects either 1 or 0.
Structural weirdness (possibly typos?)
Here's the sample request for ActivateScene:
{
"CommandType":"ActivateScene",
"MobileInternalIndex":"324",
"Scenes":{
"ID":"11"
}
}
Should the "Scenes" attribute be an array?
Yes, it is in Array format, however, we will not allow multiple scenes at a time.
-
Since this websocket is completely insecure, I assume/hope it is only exposed on the internal interface.
Is the intention to keep it local network only, even if it is secured?
-
Hello all. Trying to access the websocket on my almond 3 using the chrome simple web socket client. Which/what password do I need to use in the URL? Is it the same password to access the local web interface? Thanks
-
@bmwilson55 If you haven't found the answer by now, you need to use the username & password for the local web interface.
I'd love to see some explanatory text added to the DeviceList doc. The Websockets API doc is not very helpful with regards to knowing what "Type" values map to what "Device" with specific "DeviceValues" (capabilities). In fact, I glossed past the sections of the websockets doc most relevant to me because I didn't grok that a "DeviceIndex" is how we're supposed to interact with and read/change a devices properties.
There's an entire column for "Remarks" that is just begging for some explanations. For starters, what do the 5 different values for DoorLock LOCK_STATE symbolize? I'm assuming something along the lines of open, closed, opening, closing, and maybe unknown, but I don't have a lock to test with and they are unlabeled in the doc. Also, what are the practical differences between the data types Byte, Int, Decimal, Unsigned-Char, and Unsigned-Char(Decimal) when the value ranges seem almost interchangeable? I'm familiar with the usual difference between, say, a byte (8-bit, 0-255) vs an integer (at least 16-bit, 0-65,536), but I see a lot of interchangeable types (Byte, Decimal) for number ranges of 0-255 and 0-100.
Why are my non-colored Hue bulbs showing up as Type 4 (MultilevelSwitchOnOff) with extra undocumented device values that correspond with Type 48 (HueLamp) but in a different order? And is there any documentation on the Type values associated with each DeviceValue?
And what are all the references to XML about? The websockets API is JSON, is there another API that handles XML? Is there documentation on the XML that may have more information?
I might be interested in edit rights for the Wiki while I develop my addon for Mozilla's Things Gateway: https://github.com/cr0ybot/almond-adapter
-
cr0ybot,
I've had to figure a lot of these things out myself in rewriting a homebridge-almond (https://github.com/swiss6th/homebridge-almond) plugin. You're welcome to look at how I interpreted the Almond's JSON values. Particularly, the GarageDoorOpener (https://github.com/swiss6th/homebridge-almond/blob/7325eb8ce856d431560d5e44b95b4ef51b780948/index.js#L1109) and DoorLock (https://github.com/swiss6th/homebridge-almond/blob/7325eb8ce856d431560d5e44b95b4ef51b780948/index.js#L1239) states needed a lot of trial-and-error. There are still a bunch of device types I haven't tackled yet, as I only have so many sensors on hand. Pardon my disdain for semicolons. ;)
-
@Square Cherry your work will be an invaluable reference, thank you! I may be interested in using your almond-client as a dependency, though I see your edits have not been merged upstream to the npm-connected repo. I've already got the websocket connection working, but this looks like it has many useful features and it would be silly to duplicate the effort.
-
cr0ybot,
Please use whatever you'd like! I am new to Git, and I'm not quite sure how to merge upstream. I introduced some breaking changes in my fork, anyway. It's not backwards-compatible to Thomas Purchas' original. If I knew how to push my changes upstream, even to NPM, that'd be cool (if no one objected). I just haven't looked into the process.
Some warnings about almond-client:
You might notice that I'm not using its callback feature in homebridge-almond. In some of the early versions, I realized the Almond is quite slow in sending "updates" after a change has been written. That's why I made the feature optional (see the function signatures). A consequence is that I have not gotten around to testing this logic thoroughly, so be careful. All almond-client does by default is wait for the "Success" response, which seems more like an acknowledgment than a confirmation.
Also, beware that the keepalive timing is quite aggressive (about once per second, if I recall). You may need to adjust this if you need multiple client connections for your project. It could get "spammy" easily.
-
Thanks @Square Cherry.
You won't be able to take ownership over a published npm package without the owner's permission, and since your fork is from another fork, I'm not sure what the GitHub-specific process is to create a pull request to the originating repo.
I think I'll end up referencing some of the work you did with keeping the socket alive and possibly incorporating the EventEmitter class, but it may end up being more work to incorporate almond-client wholesale. I've also got my own system for tracking responses to requests using a Promise-based system which I'd like to develop further.
Since this thread is ostensibly for API feedback, I'm working on my own mapping from the DeviceTypes list to Mozilla's Web of Things Capabilities schema (https://mozilla-iot.github.io/schemas) (it's early days, so pretty limited in scope currently), and I've noticed a few more discrepancies. For starters, definitions for IDs 35, 42, 47, and 51 are missing. I suppose IDs don't necessarily need to be sequential, but a note like "Unused" might be helpful. Also, #56 EnergyReader is listed twice.
-
I think I'll end up referencing some of the work you did with keeping the socket alive and possibly incorporating the EventEmitter class, but it may end up being more work to incorporate almond-client wholesale. I've also got my own system for tracking responses to requests using a Promise-based system which I'd like to develop further.
Fair. I know Promises are the way to go, but I'd finally wrapped my head around EventEmitter. I will probably rewrite using Promises someday, once I get more comfortable with them. Perhaps I should take a look at your client system for reference. ;)
Since this thread is ostensibly for API feedback, I'm working on my own mapping from the DeviceTypes list to Mozilla's Web of Things Capabilities schema (https://mozilla-iot.github.io/schemas) (it's early days, so pretty limited in scope currently), and I've noticed a few more discrepancies. For starters, definitions for IDs 35, 42, 47, and 51 are missing. I suppose IDs don't necessarily need to be sequential, but a note like "Unused" might be helpful. Also, #56 EnergyReader is listed twice.
Yeah, I consulted that Devicelist Documentation (https://wiki.securifi.com/index.php/Devicelist_Documentation) when making my short version in JSON (https://github.com/swiss6th/almond-client/blob/master/devicePersonalities.json). I'm not sure where it came from, but it isn't terribly consistent. It seems like the only resource we have for now. There's a reason I'm only supporting a few types in my homebridge-almond fork.