Giter Site home page Giter Site logo

koalazak / rest980 Goto Github PK

View Code? Open in Web Editor NEW
291.0 38.0 62.0 55 KB

REST interface to control your iRobot Roomba 980 via local server on your lan.

License: MIT License

JavaScript 80.12% CSS 0.29% Dockerfile 2.83% EJS 16.76%
irobot roomba roomba980 dorita980 docker-image dockerfile cloud api rest robot iot

rest980's Introduction

rest980

rest980 create a http server to map all dorita980 methods in a REST API to control your iRobot Roomba 900 series 980 / i7 / i7+ via HTTP requests.

Install

$ git clone https://github.com/koalazak/rest980.git
$ cd rest980
$ npm install

Fimrware version

Check your robot firmware version! and set your firmware version in firmwareVersion rest980 configuration!

Configuration

The service can be configured by editing config/default.json or by setting environment variables.

Config File (config/default.json) Environment Description
port PORT (default:3000) The HTTP port to listen on.
blid BLID (required) The Roomba blid. *
password PASSWORD (required) The Roomba password. *
robotIP ROBOT_IP (optional) Set if you know your robot IP to skip discovery and speed up startup.
firmwareVersion FIRMWARE_VERSION (optional) Set to 1 or 2 depends of your robot firmware version. Use 2 for any firmware >=2 (yes, use 2 if you have firmware version 3). Default to 1 for firmware 1.6.6
enableLocal ENABLE_LOCAL (optional) Set to 'no' if you want to disable local API. Default 'yes'.
enableCloud ENABLE_CLOUD (optional) Set to 'no' if you want to disable cloud API. Default 'yes'.
keepAlive KEEP_ALIVE (optional) Set to 'no' if you want to connect and disconnect to the robot in each request (slow but leave the connection free for the official mobile app).
basicAuthUser BASIC_AUTH_USER (optional) Set to enable basic auth. Both user and pass must be set.
basicAuthPass BASIC_AUTH_PASS (optional) Set to enable basic auth. Both user and pass must be set.
sslKeyFile SSL_KEY_FILE (optional) Set path to key file to enable HTTPS. Both key and cert must be set. (how to create self signed cert)
sslCertFile SSL_CERT_FILE (optional) Set path to cert file to enable HTTPS. Both key and cert must be set. (how to create self signed cert)

See dorita980 for more information and instructions for obtaining your robot blid and password

Start API Server

$ cd rest980
$ DEBUG=rest980:* npm start
rest980:server Listening on port 3000

omit DEBUG=rest980:* if you want. You can just run with npm start

Or use Docker Image

You can use koalazak/rest980 docker image to run this server in a docker container. Usefull to run on Synology for example.

Pull Docker image:

docker pull koalazak/rest980

Run Docker image:

docker run -e BLID=myuser -e PASSWORD=mypass -e ROBOT_IP=myrobotIP koalazak/rest980

Dockerfile

Also you can local build and test in Docker from this Dockerfile

docker build . -t koalazak/rest980 

API documentation

Now you can make request to this server on port 3000. There are 2 main endpoints: local and cloud, mapped to dorita980 local and cloud methods as well.

Error responses:

HTTP status 500 and response:

{"message":"human message","error":{}}

Local

Actions

All cleaning actions are under /api/local/action/[action] endpoint using GET method without query params:

Available actions:

  • start
  • stop
  • pause
  • dock
  • resume
  • cleanRoom

Example: start to clean

GET http://192.168.1.110:3000/api/local/action/start

Success Response:

{"ok":null,"id":23}

Example: clean a specific room

Some roomba types support "room specificic cleaning" - at the time of writing, at least the s9 and the i7 support this featrue. Assuming you have this model, and have a "Smart Map" for the floor you're trying to clean, you can send room specific cleaning commands. The easiest way to find out the values for this is to start a room specific clean via the app, and then look at the state endpoint (documented below) and find the lastCommand entry. Using this, you can find the room ids. These seem to be stable over time, unless a re-training or new smart map is saved.

The pmap_id and user_pmapv_id are also derived from the same lastCommand trick. These also seem to be stable - unless a new training run or edit to the smart map happens. It's important to get these correct, else your roomba won't clean.

curl -X POST http://192.168.1.110:3000/api/local/action/cleanRoom -H 'Content-Type: application/json' -d '{"ordered": 0, "pmap_id": "123456", "regions": [{"region_id":"5", "region_name":"Hallway","region_type":"hallway"}], "user_pmapv_id": "987654"}'

Note that this is a POST becuase it has a body, unlike the other related action methods.

Info

All info endpoints are under /api/local/info/[record] using GET method without query params:

Available records:

  • mission
  • wireless
  • lastwireless
  • sys
  • sku
  • state (only in firmware 2)

Example: get current mission variables

GET http://192.168.1.110:3000/api/local/info/mission

Success Response:

{ "ok":
   { "flags": 0,
     "cycle": "none",
     "phase": "charge",
     "pos": { "theta": 179, "point": {"x": 102, "y": -13} },
     "batPct": 99,
     "expireM": 0,
     "rechrgM": 0,
     "error": 0,
     "notReady": 0,
     "mssnM": 0,
     "sqft": 0 },
  "id": 2 }

Configurations

All configuration endpoints are under /api/local/config/[configName] using GET method to get current configuration and POST method to set a new configuration.

Available configName:

  • ptime (only GET in firmware 1)
  • bbrun (only GET)
  • cloud (only GET)
  • langs (only GET. Use preferences to set lang)
  • week
  • time (POST Y GET in firmware 1. Only GET in Firmware 2)
  • preferences
  • carpetBoost/auto (only POST. Use preferences to get current config)
  • carpetBoost/performance (only POST. Use preferences to get current config)
  • carpetBoost/eco (only POST. Use preferences to get current config)
  • edgeClean/on (only POST. Use preferences to get current config)
  • edgeClean/off (only POST. Use preferences to get current config)
  • cleaningPasses/auto (only POST. Use preferences to get current config)
  • cleaningPasses/one (only POST. Use preferences to get current config)
  • cleaningPasses/two (only POST. Use preferences to get current config)
  • alwaysFinish/on (only POST. Use preferences to get current config)
  • alwaysFinish/off (only POST. Use preferences to get current config)

See dorita980 documentation for responses and body params for each method and version firmware.

Examples:

Get preferences in firmware 1:

GET http://192.168.1.110:3000/api/local/config/preferences

Success Response:

{ ok:
   { flags: 1024, // See Cleaning Preferences table in dorita980 documentation.
     lang: 2,
     timezone: 'America/Buenos_Aires',
     name: 'myRobotName',
     cleaningPreferences: {
        carpetBoost: 'auto', // 'auto', 'performance', 'eco'
        edgeClean: true,
        cleaningPasses: '1', // '1', '2', 'auto'
        alwaysFinish: true 
      }
    },
 id: 2 }

See dorita980 documentation for preferences in firmware 2.

Set preferences in firmware 1:

POST http://192.168.1.110:3000/api/local/config/preferences

Body:

{ 
  "flags": 1107, // See Cleaning Preferences table in dorita980 documentation.
  "lang": 2,
  "timezone": "America/Buenos_Aires",
  "name": "myRobotName"
}

Success Response:

{"ok":null,"id":293}

See dorita980 documentation for preferences in firmware 2.

Set cleaning passes to two:

POST http://192.168.1.110:3000/api/local/config/cleaningPasses/two

Body:

{}

Success Response:

{"ok":null,"id":293}

Cloud (only for firmware 1.6.x)

Use GET in all info endpoints without query params:

  • /api/cloud/info/status
  • /api/cloud/info/history
  • /api/cloud/info/missionHistory

Use GET in all action endpoints without query params:

  • /api/cloud/action/clean
  • /api/cloud/action/quick
  • /api/cloud/action/spot
  • /api/cloud/action/dock
  • /api/cloud/action/start
  • /api/cloud/action/stop
  • /api/cloud/action/pause
  • /api/cloud/action/resume
  • /api/cloud/action/wake
  • /api/cloud/action/reset
  • /api/cloud/action/find
  • /api/cloud/action/wipe
  • /api/cloud/action/sleep
  • /api/cloud/action/off
  • /api/cloud/action/fbeep

Example:

GET http://192.168.1.110:3000/api/cloud/action/clean

Success Response:

{"status":"OK","method":"multipleFieldSet"}

Host images or files

You can add images or files to public/ folder to serve static files.

Realtime Map (experimental)

Visiting http://serverIP:3000/map with your browser you can play with this cool experiment

/map

iRobot Roomba 980 cleaning map using dorita980 lib

Video: Realtime cleaning map

rest980's People

Contributors

allanglen avatar jeremywillans avatar koalazak avatar mindstorms6 avatar rdewolff avatar ypresto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rest980's Issues

Spot clean on map

Maybe show the coordinates where the robot decided to perform a spot clean on the map. Is this possible?

Error: Connection refused: Not authorized

Error message:

[email protected] start /opt/loxberry/rest980
node ./bin/www

/opt/loxberry/rest980/node_modules/dorita980/lib/v2/local.js:32
throw e;
^

Error: Connection refused: Not authorized
at MqttClient._handleConnack (/opt/loxberry/rest980/node_modules/mqtt/lib/client.js:920:15)
at MqttClient._handlePacket (/opt/loxberry/rest980/node_modules/mqtt/lib/client.js:350:12)
at work (/opt/loxberry/rest980/node_modules/mqtt/lib/client.js:292:12)
at Writable.writable._write (/opt/loxberry/rest980/node_modules/mqtt/lib/client.js:302:5)
at doWrite (/opt/loxberry/rest980/node_modules/readable-stream/lib/_stream_writable.js:428:64)
at writeOrBuffer (/opt/loxberry/rest980/node_modules/readable-stream/lib/_stream_writable.js:417:5)
at Writable.write (/opt/loxberry/rest980/node_modules/readable-stream/lib/_stream_writable.js:334:11)
at TLSSocket.ondata (_stream_readable.js:556:20)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:177:18)
at TLSSocket.Readable.push (_stream_readable.js:135:10)
at TLSWrap.onread (net.js:542:20)

npm ERR! Linux 4.4.13-v7+
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "start"
npm ERR! node v6.4.0
npm ERR! npm v3.10.3
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: node ./bin/www
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script 'node ./bin/www'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the rest980 package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node ./bin/www
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs rest980
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls rest980
npm ERR! There is likely additional logging output above.
npm ERR! Linux 4.4.13-v7+
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "start"
npm ERR! node v6.4.0
npm ERR! npm v3.10.3
npm ERR! path npm-debug.log.2013081302
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall open

npm ERR! Error: EACCES: permission denied, open 'npm-debug.log.2013081302'
npm ERR! at Error (native)
npm ERR! { Error: EACCES: permission denied, open 'npm-debug.log.2013081302'
npm ERR! at Error (native)
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'open',
npm ERR! path: 'npm-debug.log.2013081302' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

npm ERR! Please include the following file with any support request:
npm ERR! /opt/loxberry/rest980/npm-debug.log

npm-debug.log:

0 info it worked if it ends with ok
1 verbose cli [ '/usr/bin/nodejs', '/usr/bin/npm', 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info lifecycle [email protected]prestart: [email protected]
6 silly lifecycle [email protected]
prestart: no script for prestart, continuing
7 info lifecycle [email protected]start: [email protected]
8 verbose lifecycle [email protected]
start: unsafe-perm in lifecycle true
9 verbose lifecycle [email protected]start: PATH: /usr/lib/node_modules/npm/bin/no$
10 verbose lifecycle [email protected]
start: CWD: /opt/loxberry/rest980
11 silly lifecycle [email protected]start: Args: [ '-c', 'node ./bin/www' ]
12 silly lifecycle [email protected]
start: Returned: code: 1 signal: null
13 info lifecycle [email protected]~start: Failed to exec start script
14 verbose stack Error: [email protected] start: node ./bin/www
14 verbose stack Exit status 1
14 verbose stack at EventEmitter. (/usr/lib/node_modules/npm/lib$
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at EventEmitter.emit (events.js:191:7)
14 verbose stack at ChildProcess. (/usr/lib/node_modules/npm/lib$
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at ChildProcess.emit (events.js:191:7)
14 verbose stack at maybeClose (internal/child_process.js:852:16)
14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_pro$
15 verbose pkgid [email protected]
16 verbose cwd /opt/loxberry/rest980
17 error Linux 4.4.13-v7+
18 error argv "/usr/bin/nodejs" "/usr/bin/npm" "start"
19 error node v6.4.0
20 error npm v3.10.3
21 error code ELIFECYCLE
22 error [email protected] start: node ./bin/www
22 error Exit status 1
23 error Failed at the [email protected] start script 'node ./bin/www'.
23 error Make sure you have the latest version of node.js and npm installed.
23 error If you do, this is most likely a problem with the rest980 package,
23 error not with npm itself.
23 error Tell the author that this fails on your system:
23 error node ./bin/www

Running on Docker (on Synology) gives me an error suddenly (crash)

Hello,

I;ve been using the REST980 for quite some time. However, I noticed it was in a reboot loop (last week).

So I took a screenshot of all my settings. Then deleted the container, deleted the image. Then did a new install (all on Synology/Docker) and entered my settings again.

It still keeps rebooting. The following is the terminal output.

image

Synology Docker Install Question

I have the lid and password setup (I believe)

When I launch the container I get this message. I think it may have something to do with my mount volume?

screen shot 2018-10-10 at 9 11 53 pm

Can not start

Hello. I get the error:

info it worked if it ends with ok
1 verbose cli [ '/usr/bin/node', '/usr/bin/npm', 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info lifecycle [email protected]prestart: [email protected]
6 silly lifecycle [email protected]
prestart: no script for prestart, continuing
7 info lifecycle [email protected]start: [email protected]
8 verbose lifecycle [email protected]
start: unsafe-perm in lifecycle true
9 verbose lifecycle [email protected]start: PATH: /usr/lib/node_modules/npm/bin/no$
10 verbose lifecycle [email protected]
start: CWD: /home/se.ki/node_modules/rest980
11 silly lifecycle [email protected]start: Args: [ '-c', 'node ./bin/www' ]
12 silly lifecycle [email protected]
start: Returned: code: 1 signal: null
13 info lifecycle [email protected]~start: Failed to exec start script
14 verbose stack Error: [email protected] start: node ./bin/www
14 verbose stack Exit status 1
14 verbose stack at EventEmitter. (/usr/lib/node_modules/npm/lib$
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at EventEmitter.emit (events.js:191:7)
14 verbose stack at ChildProcess. (/usr/lib/node_modules/npm/lib/utils/spawn$
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at ChildProcess.emit (events.js:191:7)
14 verbose stack at maybeClose (internal/child_process.js:920:16)
14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:230:$
15 verbose pkgid [email protected]
16 verbose cwd /home/se.ki/node_modules/rest980
17 error Linux 4.9.59-v7+
18 error argv "/usr/bin/node" "/usr/bin/npm" "start"
19 error node v6.12.0
20 error npm v3.10.10
21 error code ELIFECYCLE
22 error [email protected] start: node ./bin/www
22 error Exit status 1
23 error Failed at the [email protected] start script 'node ./bin/www'.
23 error Make sure you have the latest version of node.js and npm installed.
23 error If you do, this is most likely a problem with the rest980 package,
23 error not with npm itself.
23 error Tell the author that this fails on your system:
23 error node ./bin/www
23 error You can get information on how to open an issue for this project with:
23 error npm bugs rest980
23 error Or if that isn't available, you can get their info via:
23 error npm owner ls rest980
23 error There is likely additional logging output above.
24 verbose exit [ 1, true ]

Can u help me?

Node-RED

Please create a nodered app, may take one of these as a base 1, 2

There only two tools at nodered for Roomba 980 which both use your repo flows.nodered.org/.. But it seems they do not anymore update. It would be nice if there is an updated repo and may in future an UI_Dashboard with the "Realtime Map".

At moment, I use Node-RED with App 1 at Home for command my Roomba by a CalDAV Calendar.

If you need I would like to be a beta tester for the nodered repo.

Problem with Firmware 2 and REST with environment variables

Hi,

first: thanks for this api - a very good solution - i really like it!

I use the docker installation with environment variables:
ENABLE_LOCAL yes; KEEP_ALIVE no; ENABLE_CLOUD no; FIRMWARE_VERSION 2; PASSWORT ...; ROBOT_IP ...; BLID ...

With KEEP_ALIVE yes everything works. With KEEP_ALIVE no there comes an error:

TypeError: Cannot read property 'getMission' of undefined at /usr/src/app/routes/api.js:149:20

This error appears because the condition in line 146 isn't true. keepAlive is 'no', but firmwareVersion seems to be a string. If I change the condition to

if (keepAlive === 'no' && firmwareVersion === '2') {

everything works.

There are other lines with a firmwareVersion compare.
And I don't know if the variable is an integer using config file.

Thanks, Norman

Cannot read property.

I got everything installed on Docker and when I attempt to run any command nothing happens and my log states “Can’t read property [command]...”

Any ideas?

Roomba 980 reject requests

Hello,

I'm sending request to my Roomba980 every minute using rest980 because I need to know if bin is full or not. If it's full, my Karotz say it until I move my lazy ass.

Sometimes, everything in ./api/local loads forever and never gives me an answer but :
-I can see ./ or ./api/
-I'm still able to ping Roomba from my local server where rest980 is installed
-iRobot app loads correctly, in LTE and Wifi.
-Restarting rest980 doesn't fix the issue
-Restarting Roomba sometimes fix the issue, if not, I need to reset Roomba and get a new password

Any idea ?

Thanks.
Goshi.

Docker config mismatch

Hi,

in your Dockerfile, you set the env var NODE_ENV to "production". This causes the REST framework to look for the configuration file "config/production.json", resulting either in a warning (if you provide blid, pw & ip through env var):

WARNING: NODE_ENV value of 'production' did not match any deployment config file names.
WARNING: See https://github.com/lorenwest/node-config/wiki/Strict-Mode

or in an exception:

/usr/src/app/routes/api.js:21
throw new Error('Config not found. Please edit config/default.json file with your robot credentials. Or set BLID, PASSWORD and ROBOT_IP enviroment variables.');
...

Thanks
Dominik

Maintenance Flags?

Hi Zak,

Awesome job on this service! I got the docker container up and running without issue. Just wanted to ask if you can help identify the roomba's maintenance flags like bin full, rollers blocked, sensors dirty, etc?

Thanks!

No blid/username output!?

In the README.dm it stats that running
$ npm run getpassword <robotIP>
one gets that blid/username:

Looking for robots...
Robot found! with blid/username: xxxxxxxxxxxxx

However in the output I've got the blid/username line is missing:

Maresia:dorita980 rmnm$ npm run getpassword 192.168.1.66

[email protected] getpassword /Users/someUser/dorita980
node ./bin/getpassword.js "192.168.1.66"

Make sure your robot is on the Home Base and powered on (green lights on). Then press and hold the HOME button on your robot until it plays a series of tones (about 2 seconds). Release the button and your robot will flash WIFI light.
Then press any key here...
Robot Data:
{ ver: '2',
hostname: 'Roomba-6943C91C12422640',
robotname: 'Raft',
ip: '192.168.1.66',
mac: '80:A5:89:60:D8:48',
sw: 'v2.0.0-34',
sku: 'R98----',
nc: 0,
proto: 'mqtt',
blid: '6943C91C12422640' }
Password=> **************** <= Yes, all this string.
Use this credentials in dorita980 lib :)

Looking to dorita980.getRobotIP() maybe I can get hold of the blid/username, is that right?

Roomba 960 support?

Apologies if this is answered somewhere, but does this support the Roomba 960? It seems to have the same connectivity as the 980 but is quite a bit cheaper.

Nginx: add context root

Add a context root to make it easier to federate application with a nginx reverse proxy

  • Add parameter for context root
  • Change URIs using context root
  • Change Nginx configuration

500 Error: Connection Refused

Not sure if this rest980 API is supposed to share compatibility with anything that dorita980 works with, so please clarify that for me to begin with.

I have a iRoomba 690 on firmware 3, has been working just fine with dorita980. I am able to run the rest980 API and load the /map page, but all of the requests to my robot's local IP address fail with 500 error.

GET /api/local/action/dock 500 1031.496 ms - 1438
RequestError: Error: connect ECONNREFUSED 192.168.1.105:443
at new RequestError (C:\Users\jackt\node_modules\rest980\node_modules\request-promise-core\lib\errors.js:14:15)
at Request.plumbing.callback (C:\Users\jackt\node_modules\rest980\node_modules\request-promise-core\lib\plumbing.js:87:29)
at Request.RP$callback [as _callback] (C:\Users\jackt\node_modules\rest980\node_modules\request-promise-core\lib\plumbing.js:46:31)
at self.callback (C:\Users\jackt\node_modules\rest980\node_modules\request\request.js:185:22)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
at Request.onRequestError (C:\Users\jackt\node_modules\rest980\node_modules\request\request.js:881:8)
at emitOne (events.js:116:13)
at ClientRequest.emit (events.js:211:7)
at TLSSocket.socketErrorListener (_http_client.js:387:9)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)

Live update via websockets

  • Add websocket api to read mission and send updates
  • Use websockets from UI
  • Configure Nginx for websockers

Actions are not working

Hi,
first of all, thanks for your effort to create thos repo and Dockerfile. It cost me only a hour to get the Rest-Server running.

The Server can get preferences, missing etc, but all mentioned Actions are not working.

E.g.

Get http://syn:3000/api/local/action/start

Resonse: {
"ok": null
}

iRobot Firmware: 2.4.6-3

I double cheked with map, but even there no activities.

Do you have an idea?

Map Feature in REST980

To quote you Koalazak:

my plan is add a path in rest980 where you will see the map and some controls via web in your browser. While the api is in /api/loca/... this new page will be in /map in rest980 server.

When you visit /map the server side start to make getMission calls to get the x,y position every 800ms, sending this data to the browser via websockets. Then in client side, the browser draws each point received in the map (html canvas). No image, just a html canvas.

I think that is way to complex... Of course it's technically very nice but what about

  • Different browsers,.. even looking on your iPhone/iPad (safari) or including it in an iFrame
  • You need to have a connection open all the time..? What if you just want to see (at the end of the day when you come back home) the map that was made when your Roomba cleaned during the day.

I think including a basic image library and have a Node 'service' running which puts the coordinates (as dots or lines) into the image is more convenient. You can even ask the map like /map?res=640x490 or /map?res=1024x768 and even something like /map?res=1024x768background=myfloorplan.gif

The use cases of just a static image are endless.
And even better: Since REST980 is a REST interface. You can even connect it to IFTTT and (at the end of the cleaning) let the Roomba (via IFTTT or directly) e-mail you a "I cleaned your house!" email with the map as an attachment.
(PS. Since we don't want to pay 10.000$ to IFTTT to include a REST980 channel. You can just use the 'MAKER' channel, I have used that for other things also)

What do you think?

(PS. Tomorrow I will post some screenshots.. tutorial..etc..)

Autobuild ARMv7 Container

Is there a possibility of Auto Building a armv7 container on Docker Hub?

I have successfully built and tested this on a Raspberry Pi , using node:alpine.

It does however complain about missing favicon.ico

Creating rest980 ... done
Attaching to rest980
rest980    | 
rest980    | > [email protected] start /usr/src/app
rest980    | > node ./bin/www
rest980    | 
rest980    | WARNING: NODE_ENV value of 'production' did not match any deployment config file names.
rest980    | WARNING: See https://github.com/lorenwest/node-config/wiki/Strict-Mode
rest980    | GET / 200 36.481 ms - 89
rest980    | GET /favicon.ico 404 5.961 ms - 136
rest980    | Error: Endpoint not found.
rest980    |     at /usr/src/app/app.js:62:13
rest980    |     at Layer.handle [as handle_request] (/usr/src/app/node_modules/express/lib/router/layer.js:95:5)
rest980    |     at trim_prefix (/usr/src/app/node_modules/express/lib/router/index.js:317:13)
rest980    |     at /usr/src/app/node_modules/express/lib/router/index.js:284:7
rest980    |     at Function.process_params (/usr/src/app/node_modules/express/lib/router/index.js:335:12)
rest980    |     at next (/usr/src/app/node_modules/express/lib/router/index.js:275:10)
rest980    |     at /usr/src/app/node_modules/express/lib/router/index.js:635:15
rest980    |     at next (/usr/src/app/node_modules/express/lib/router/index.js:260:14)
rest980    |     at jsonParser (/usr/src/app/node_modules/body-parser/lib/types/json.js:110:7)
rest980    |     at Layer.handle [as handle_request] (/usr/src/app/node_modules/express/lib/router/layer.js:95:5)
rest980    |     at trim_prefix (/usr/src/app/node_modules/express/lib/router/index.js:317:13)
rest980    |     at /usr/src/app/node_modules/express/lib/router/index.js:284:7
rest980    |     at Function.process_params (/usr/src/app/node_modules/express/lib/router/index.js:335:12)
rest980    |     at next (/usr/src/app/node_modules/express/lib/router/index.js:275:10)
rest980    |     at Function.handle (/usr/src/app/node_modules/express/lib/router/index.js:174:3)
rest980    |     at router (/usr/src/app/node_modules/express/lib/router/index.js:47:12)
rest980    |     at Layer.handle [as handle_request] (/usr/src/app/node_modules/express/lib/router/layer.js:95:5)
rest980    |     at trim_prefix (/usr/src/app/node_modules/express/lib/router/index.js:317:13)
rest980    |     at /usr/src/app/node_modules/express/lib/router/index.js:284:7
rest980    |     at Function.process_params (/usr/src/app/node_modules/express/lib/router/index.js:335:12)
rest980    |     at next (/usr/src/app/node_modules/express/lib/router/index.js:275:10)
rest980    |     at authHandler (/usr/src/app/app.js:23:48)

Log missions on the server

  • Parameter to enable server logging, and retantion period
  • Monitor and append data
  • Create a new file for any new mission
  • Automatically load current mission from browser
  • List and load missions from browser
  • auto cleanup logged missions

Crashes after time?

I created a service file for rest980.
But after some time the services seems to crash.
Till now I got no crash report. May be I did something wrong in the service file? Or is there a better way to start it as a service?

See my attached service file:
rest980.txt

Some actions not responded

Hello,
For some time all works perfect, but from yesterday i have problem, that some commands (for example: info/mission, info/sys) not works (they not load). Other commands like: info/wireless, info/state works OK. Also starting iRobot works.

PS: It all started after a power outage.

Getpassword in RES980

Wouldn't it be cool to have the Getpassword method in the REST980 interface?

Since issue #11 (of dorita) it is already in the dorita package. But not yet in the rest980.

I helped a few people in setting up their robot with the rest library (on a synology) and noticed it was quite a job to get the password (install nodes, etc. on a Windows PC sucks) and installing an Ubuntu release with VNC on a synology, install git, nodes, etc. takes more than 1 hour time..

Timeour errors in rest980/dorita980

Hi there,
I'm trying your tools for roomba980 but I'm getting a lot of timeout errors.

Every RestPoint/function which leads only to your local methods (root API point, /map,...) are proceed immediately, but any connection to Roomba usually leads to a timeout. Sometime command is proceeded after 3-5minutes.

But commands made from iRoomba app (connected to the same network) are proceed withing few msec.

RequestError: Error: connect ETIMEDOUT 192.168.6.109:443
    at new RequestError (/home/dev/rest980/node_modules/request-promise-core/lib/errors.js:14:15)
    at Request.plumbing.callback (/home/dev/rest980/node_modules/request-promise-core/lib/plumbing.js:87:29)
    at Request.RP$callback [as _callback] (/home/dev/rest980/node_modules/request-promise-core/lib/plumbing.js:46:31)
    at self.callback (/home/dev/rest980/node_modules/request/request.js:186:22)
    at emitOne (events.js:77:13)
    at Request.emit (events.js:169:7)
    at Request.onRequestError (/home/dev/rest980/node_modules/request/request.js:845:8)
    at emitOne (events.js:77:13)
    at ClientRequest.emit (events.js:169:7)
    at TLSSocket.socketErrorListener (_http_client.js:258:9)
    at emitOne (events.js:77:13)
    at TLSSocket.emit (events.js:169:7)
    at emitErrorNT (net.js:1256:8)
    at nextTickCallbackWith2Args (node.js:441:9)
    at process._tickCallback (node.js:355:17)

Do you have any idea where can be a problem? I tried it on several places on my home where wifi signal is strong enough for any other device and it seems that this is not a problem.

Thank you
Ludek

Unable to start npm

I was using rest980 for quite some time on my Raspberry Pi and a Roomba980 without any issues. A few weeks ago it stoped working and I could not solve the issue, so I reinstalled rest980 again but it fails already when starting. Below the message I receive. Thanks for your feedback.

root@loxberry:/opt/roomba/rest980# npm start

[email protected] start /opt/roomba/rest980
node ./bin/www
Port 3000 is already in use
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: node ./bin/www
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2019-10-16T20_50_00_799Z-debug.log

root@loxberry:/.npm/_logs# tail 2019-10-16T20_50_00_799Z-debug.log
17 verbose argv "/usr/bin/node" "/usr/bin/npm" "start"
18 verbose node v10.15.1
19 verbose npm v6.7.0
20 error code ELIFECYCLE
21 error errno 1
22 error [email protected] start: node ./bin/www
22 error Exit status 1
23 error Failed at the [email protected] start script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]
root@loxberry:
/.npm/_logs#

Connection refused

Hi there,

I've got an Roomba960 and setted up rest980 on a RaspberryPi3.
When trying to start the map the following error shows up:

pi@raspberrypi:~/Roomba/rest980 $ npm start

[email protected] start /home/pi/Roomba/rest980
node ./bin/www

GET /map 304 58.307 ms - -
GET /css/style.css 304 16.117 ms - -
GET /js/map.js 304 3.318 ms - -
GET /api/local/info/mission 500 158.811 ms - 1379
RequestError: Error: connect ECONNREFUSED 192.168.188.21:443
at new RequestError (/home/pi/Roomba/rest980/node_modules/request-promise-core/lib/errors.js:14:15)
at Request.plumbing.callback (/home/pi/Roomba/rest980/node_modules/request-promise-core/lib/plumbing.js:87:29)
at Request.RP$callback [as _callback] (/home/pi/Roomba/rest980/node_modules/request-promise-core/lib/plumbing.js:46:31)
at self.callback (/home/pi/Roomba/rest980/node_modules/request/request.js:185:22)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
at Request.onRequestError (/home/pi/Roomba/rest980/node_modules/request/request.js:877:8)
at emitOne (events.js:116:13)
at ClientRequest.emit (events.js:211:7)
at TLSSocket.socketErrorListener (_http_client.js:401:9)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at emitErrorNT (internal/streams/destroy.js:73:8)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickCallback (internal/process/next_tick.js:181:9)

BLID and password query was successful, not sure where to search else.

Thx for your help!

BR
Robin

Stop and Dock in one request

To dock the roomba you first need to call stop.

Can you please make this as one request in the API?

/api/local/action/home or something

Map not drawing with Roomba 890

Great api but I've tried two different web browsers and the map (I know it's experimental) isn't being drawn with my Roomba 890.

Use Docker Compose from portainer and got this error

I use the Portainer example you provided and swap to my BLID, PASSWORD etc. The only difference is I swapped "3000:3000" to "3060:3060" because port 3000 an8080 has already been used. When I try to start the docker image, I got the npm error. Please see log below

# Docker Portainer Stack
###################################
version: "2"
services:
  rest980:
    container_name: rest980
    image: koalazak/rest980:latest
    ports:
      - "3060:3060"
    environment:
      - BLID=<BLID>
      - PASSWORD=<PW>
      - ROBOT_IP=<IP>
      - FIRMWARE_VERSION=2
    restart: unless-stopped
  php-nginx:
    container_name: php-nginx
    image: webhippie/php-nginx:latest
    environment:
      NGINX_WEBROOT: "/app"
    volumes:
      - /mnt/data/supervisor/homeassistant/vacuum:/app
    ports:
      - "3001:6666"
    restart: unless-stopped
    at new cloud (/usr/src/app/node_modules/dorita980/index.js:12:10)


    at /usr/src/app/routes/api.js:33:46


    at handleIP (/usr/src/app/routes/api.js:26:68)


    at Object.<anonymous> (/usr/src/app/routes/api.js:27:1)


    at Module._compile (module.js:577:32)


    at Object.Module._extensions..js (module.js:586:10)


    at Module.load (module.js:494:32)


    at tryModuleLoad (module.js:453:12)


    at Function.Module._load (module.js:445:3)


    at Module.require (module.js:504:17)


    at require (internal/module.js:20:19)


    at Object.<anonymous> (/usr/src/app/app.js:11:16)


    at Module._compile (module.js:577:32)


    at Object.Module._extensions..js (module.js:586:10)


    at Module.load (module.js:494:32)


    at tryModuleLoad (module.js:453:12)


    at Function.Module._load (module.js:445:3)


    at Module.require (module.js:504:17)


    at require (internal/module.js:20:19)


    at Object.<anonymous> (/usr/src/app/bin/www:7:11)


    at Module._compile (module.js:577:32)




npm ERR! Linux 5.7.0-0.bpo.2-amd64


npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"


npm ERR! node v6.17.1


npm ERR! npm  v3.10.10


npm ERR! code ELIFECYCLE


npm ERR! [email protected] start: `node ./bin/www`


npm ERR! Exit status 1

�


 


npm ERR! Failed at the [email protected] start script 'node ./bin/www'.


npm ERR! Make sure you have the latest version of node.js and npm installed.


npm ERR! If you do, this is most likely a problem with the rest980 package,


npm ERR! not with npm itself.


npm ERR! Tell the author that this fails on your system:


npm ERR!     node ./bin/www


npm ERR! You can get information on how to open an issue for this project with:


npm ERR!     npm bugs rest980


npm ERR! Or if that isn't available, you can get their info via:


npm ERR!     npm owner ls rest980


npm ERR! There is likely additional logging output above.




npm ERR! Please include the following file with any support request:


npm ERR!     /usr/src/app/npm-debug.log




> [email protected] start /usr/src/app


> node ./bin/www




WARNING: NODE_ENV value of 'production' did not match any deployment config file names.


WARNING: See https://github.com/lorenwest/node-config/wiki/Strict-Mode


/usr/src/app/node_modules/dorita980/lib/v2/cloud.js:7


  throw new Error('Not implemented.');


  ^




Error: Not implemented.


    at dorita980 (/usr/src/app/node_modules/dorita980/lib/v2/cloud.js:7:9)


    at new cloud (/usr/src/app/node_modules/dorita980/index.js:12:10)


    at /usr/src/app/routes/api.js:33:46


    at handleIP (/usr/src/app/routes/api.js:26:68)


    at Object.<anonymous> (/usr/src/app/routes/api.js:27:1)


    at Module._compile (module.js:577:32)


    at Object.Module._extensions..js (module.js:586:10)


    at Module.load (module.js:494:32)


    at tryModuleLoad (module.js:453:12)


    at Function.Module._load (module.js:445:3)


    at Module.require (module.js:504:17)


    at require (internal/module.js:20:19)


    at Object.<anonymous> (/usr/src/app/app.js:11:16)


    at Module._compile (module.js:577:32)


    at Object.Module._extensions..js (module.js:586:10)


    at Module.load (module.js:494:32)


    at tryModuleLoad (module.js:453:12)


    at Function.Module._load (module.js:445:3)


    at Module.require (module.js:504:17)


    at require (internal/module.js:20:19)


    at Object.<anonymous> (/usr/src/app/bin/www:7:11)


    at Module._compile (module.js:577:32)




npm ERR! Linux 5.7.0-0.bpo.2-amd64


npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"


npm ERR! node v6.17.1


npm ERR! npm  v3.10.10


npm ERR! code ELIFECYCLE


npm ERR! [email protected] start: `node ./bin/www`


npm ERR! Exit status 1

�


 


npm ERR! Failed at the [email protected] start script 'node ./bin/www'.


npm ERR! Make sure you have the latest version of node.js and npm installed.


npm ERR! If you do, this is most likely a problem with the rest980 package,


npm ERR! not with npm itself.


npm ERR! Tell the author that this fails on your system:


npm ERR!     node ./bin/www


npm ERR! You can get information on how to open an issue for this project with:


npm ERR!     npm bugs rest980


npm ERR! Or if that isn't available, you can get their info via:


npm ERR!     npm owner ls rest980


npm ERR! There is likely additional logging output above.




npm ERR! Please include the following file with any support request:


npm ERR!     /usr/src/app/npm-debug.log

Can't get password with Roomba960

Hi.

Can't get password with Roomba 960.
I executed commands bellow.

$ git clone https://github.com/koalazak/dorita980.git
$ cd dorita980/
$ npm install
$ npm run getpassword ${ip}
{
 ///my roomba info
}
Error getting password. Follow the instructions and try again

I tryed that with node v6.2.0 and v9.2.0. And result was same.

What can I do to get password?

Thx.

All API Calls timeout?

Every API call I make to my i7 (app says it has 1.6.6 firmware) says there is a timeout:

GET /api/local/config/preferences - - ms - -
RequestError: Error: connect ETIMEDOUT 192.168.86.38:443
at new RequestError (/home/pi/rest980/node_modules/request-promise-core/lib/errors.js:14:15)
at Request.plumbing.callback (/home/pi/rest980/node_modules/request-promise-core/lib/plumbing.js:87:29)
at Request.RP$callback [as _callback] (/home/pi/rest980/node_modules/request-promise-core/lib/plumbing.js:46:31)
at self.callback (/home/pi/rest980/node_modules/request/request.js:185:22)
at Request.emit (events.js:189:13)
at Request.onRequestError (/home/pi/rest980/node_modules/request/request.js:881:8)
at ClientRequest.emit (events.js:189:13)
at TLSSocket.socketErrorListener (_http_client.js:392:9)
at TLSSocket.emit (events.js:189:13)
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
192.168.86.38:443GET /api/local/info/mission - - ms - -
RequestError: Error: connect ETIMEDOUT 192.168.86.38:443
at new RequestError (/home/pi/rest980/node_modules/request-promise-core/lib/errors.js:14:15)
at Request.plumbing.callback (/home/pi/rest980/node_modules/request-promise-core/lib/plumbing.js:87:29)
at Request.RP$callback [as _callback] (/home/pi/rest980/node_modules/request-promise-core/lib/plumbing.js:46:31)
at self.callback (/home/pi/rest980/node_modules/request/request.js:185:22)
at Request.emit (events.js:189:13)
at Request.onRequestError (/home/pi/rest980/node_modules/request/request.js:881:8)
at ClientRequest.emit (events.js:189:13)
at TLSSocket.socketErrorListener (_http_client.js:392:9)
at TLSSocket.emit (events.js:189:13)
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)

I can't get any of the local API calls to work from rest980. Anything I should be doing? I can ping the robot's IP 192.168.86.38, but nothing seems to be listening on port 443 on its ip, I cannot telnet to it

installation question

Hi,
When I read the readme, I assume you want to software installed on the openhab server.
I try to keep my different services seperate.
Any experience with installing this on a seperate machine? If yes what is the minimum you need?
Is a raspberry PI 3 model B enough?

msg.ok.pos is undefined

Everything works well except trying to draw the map, getting a msg.ok.pos is undefined error in the console.

I doubt it's related but just in case for context : Firefox 82.0 (64-bit) on Ubuntu with a Roomba 676.

RestApi as a Linux Service

Thanks for the great Project, it works very good. What i need to do, to run the Api as as a Linux Service.

regards Klaus

Great work Koalazak!

You already made this project, great work!!

I am currently looking to make a Docker image and want to publish it.
So anyone can downloads it, set 3 parameters and Run it!

I think the way to do it is to download the docker image: Google/nodejs (latest), Then download rest980 in it. Then make some variables and then commit and publish the image.

Now everyone would be able to tun it from their Synology or even directly in Hyper-V (which supports docker images in the latest version).

Note: The docker image can be 'auto updated' but that doesn't need to happen often.. Because the rest980 can/is already auto-updated within the nodejs.

Do you have any ideas or feedback? Or do you want to publish it under this Github account?
Tell me what you think about it.

issues starting

looking for help -- new to nodejs. When I run npm start, I get a dependency error.. appreciate any help. FWIW - I have dorita running and I was able to get the blid and pw for the rest980 config file..

:~/rest980 $ npm start

[email protected] start /home/pi/rest980
node ./bin/www

/home/pi/rest980/node_modules/dorita980/index.js:2
let cloud = require('./lib/cloud');
^^^
SyntaxError: Unexpected strict mode reserved word
at Module._compile (module.js:439:25)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (/home/pi/rest980/routes/api.js:4:17)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)

npm ERR! [email protected] start: node ./bin/www
npm ERR! Exit status 8
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is most likely a problem with the rest980 package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node ./bin/www
npm ERR! You can get their info via:
npm ERR! npm owner ls rest980

Dockerfile using sources

Just a quick note that you can put a Dockerfile at the project root and build from sources instead of doing a git clone during the docker build. This allows building in Docker from local sources before the changes make their way to master. The Dockerfile would look like this:

# Use latest node
FROM node:boron

MAINTAINER koalazak <[email protected]>

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Set the node env (we only need production dependencies in the deployed image)
ENV NODE_ENV production

# Install dependencies (we deliberately just copy packages.json so we can use the cache if no package.json changes are made)
COPY package.json /usr/src/app/
RUN npm install

# Copy the sources
COPY . /usr/src/app

# Set default env
ENV BLID=
ENV PASSWORD=
ENV ROBOT_IP=
ENV PORT=3000

EXPOSE ${PORT}

# Start the REST interface!
CMD [ "npm", "start" ]

You can then build locally with:

docker build . -t koalazak/rest980 

This setup also works with automated builds on Docker Hub since it will pull the latest master before building.

Run as a Service

Hi
How do i run this as a service? I'm new to Linux but wanted to run this as a service.

Update Docker Hub Container

Is it possible to please get the Docker Hub Container updated with the latest changes for cleanRoom ?

Thanks!

Force using new dorita980 version?

Hi,
I updated my dorita980 to new Version becaus of firmware 2.x update.
I also reinstalled the rest980.
But if I tryto use it for example:
192.168.168.11:3000/api/local/info/sys

It seems to usean old version of dorita980. I get the following message inside the browser:
RequestError: Error: connect ECONNREFUSED 192.168.168.28:443
at new RequestError (/usr/share/iRobot/rest980/node_modules/request-promise-core/lib/errors.js:14:15)
at Request.plumbing.callback (/usr/share/iRobot/rest980/node_modules/request-promise-core/lib/plumbing.js:87:29)
at Request.RP$callback [as _callback] (/usr/share/iRobot/rest980/node_modules/request-promise-core/lib/plumbing.js:46:31)
at self.callback (/usr/share/iRobot/rest980/node_modules/request/request.js:186:22)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at Request.onRequestError (/usr/share/iRobot/rest980/node_modules/request/request.js:845:8)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at TLSSocket.socketErrorListener (_http_client.js:310:9)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at emitErrorNT (net.js:1278:8)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)

Setup a room

Please add a possibility to set-up several rooms with the real-time map.
May allow to draw a room into the real-time map and get an example bash code which simply run a clean in this room.

e.g.:

  • Allow drawing into the real-time map
  • have below the real-time map a text-area
    • this text-area contain an example bash script with all needed Information to start cleaning the room which is actually set-up in the real-time map

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.