diff --git a/README.md b/README.md
index 5c150f4c..fa93915e 100644
--- a/README.md
+++ b/README.md
@@ -96,6 +96,8 @@ Uses a simple read of the serial port as a file to input data. You **must** set
**68-mysql** - Allows basic access to a MySQL database. This node uses the **query** operation against the configured database. This does allow both INSERTS and DELETES. By it's very nature it allows SQL injection... *so be careful out there...*
+**69-ddbout** - Support output to Amazon DynamoDB.
+
### Time
**79-suncalc** - Uses the suncalc module to generate an output at sunrise and sunset based on a specified location. Several choices of definition of sunrise and sunset are available,
diff --git a/storage/ddb/69-ddbout.html b/storage/ddb/69-ddbout.html
new file mode 100644
index 00000000..3f0859bd
--- /dev/null
+++ b/storage/ddb/69-ddbout.html
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
diff --git a/storage/ddb/69-ddbout.js b/storage/ddb/69-ddbout.js
new file mode 100644
index 00000000..939d7d23
--- /dev/null
+++ b/storage/ddb/69-ddbout.js
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2013 Wolfgang Nagele
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+var RED = require(process.env.NODE_RED_HOME+"/red/red");
+var util = require("util");
+var aws = require("aws-sdk");
+var attrWrapper = require("dynamodb-data-types").AttributeValue;
+
+function DDBOutNode(n) {
+ RED.nodes.createNode(this, n);
+ this.credentials = RED.nodes.getNode(n.credentials);
+ this.region = n.region || "us-east-1";
+ this.table = n.table;
+
+ aws.config.update({ accessKeyId: this.credentials.accessKey,
+ secretAccessKey: this.credentials.secretAccessKey,
+ region: this.region });
+
+ var ddb = new aws.DynamoDB();
+
+ this.on("input", function(msg) {
+ if (msg != null) {
+ ddb.putItem({ "TableName": this.table,
+ "Item": attrWrapper.wrap(msg.payload) },
+ function(err, data) {
+ err && util.log(err);
+ });
+ }
+ });
+}
+RED.nodes.registerType("ddb out", DDBOutNode);
diff --git a/storage/ddb/aws.html b/storage/ddb/aws.html
new file mode 100644
index 00000000..5c26c904
--- /dev/null
+++ b/storage/ddb/aws.html
@@ -0,0 +1,68 @@
+
+
+
+
+
diff --git a/storage/ddb/aws.js b/storage/ddb/aws.js
new file mode 100644
index 00000000..9997b676
--- /dev/null
+++ b/storage/ddb/aws.js
@@ -0,0 +1,65 @@
+/**
+ * Copyright 2013 Wolfgang Nagele
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+var RED = require(process.env.NODE_RED_HOME+"/red/red");
+var querystring = require('querystring');
+
+function AWSCredentialsNode(n) {
+ RED.nodes.createNode(this, n);
+ var credentials = RED.nodes.getCredentials(n.id);
+ if (credentials) {
+ this.accessKey = credentials.accessKey;
+ this.secretAccessKey = credentials.secretAccessKey;
+ }
+}
+RED.nodes.registerType("aws credentials", AWSCredentialsNode);
+
+RED.app.get('/aws-credentials/:id', function(req, res) {
+ var credentials = RED.nodes.getCredentials(req.params.id);
+ if (credentials) {
+ res.send(JSON.stringify({ accessKey: credentials.accessKey, secretAccessKey: credentials.secretAccessKey }));
+ } else {
+ res.send(JSON.stringify({}));
+ }
+});
+
+RED.app.delete('/aws-credentials/:id', function(req, res) {
+ RED.nodes.deleteCredentials(req.params.id);
+ res.send(200);
+});
+
+RED.app.post('/aws-credentials/:id', function(req, res) {
+ var body = "";
+ req.on("data", function(chunk) {
+ body += chunk;
+ });
+ req.on("end", function() {
+ var newCreds = querystring.parse(body);
+ var credentials = RED.nodes.getCredentials(req.params.id) || {};
+ if (newCreds.accessKey == null || newCreds.accessKey == "") {
+ delete credentials.accessKey;
+ } else {
+ credentials.accessKey = newCreds.accessKey || credentials.accessKey;
+ }
+ if (newCreds.secretAccessKey == null || newCreds.secretAccessKey == "") {
+ delete credentials.secretAccessKey;
+ } else {
+ credentials.secretAccessKey = newCreds.secretAccessKey || credentials.secretAccessKey;
+ }
+ RED.nodes.addCredentials(req.params.id, credentials);
+ res.send(200);
+ });
+});