Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MQTT #10

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
config/config.json
*.log
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,25 @@ In `development` mode, it just logs to stdout.

Launch the app via `script/server` to run it in the development environment.

## Docs
## MQTT

itunes-api can report its state changes to your MQTT broker. Just edit your
config file in `config/config.json` to add your MQTT host.

itunes-api publishes topics with the namespace of: `itunes-api`.

### Topics

* `itunes-api/state`, `playing`|`paused`|`stop` - This is published whenever the
state is changed.
* `itunes-api/volume`, `45` - This is published whenever the volume level is
changed.
* `itunes-api/airplay_devices/:airplay_device_id/state`, `on`|`off` - This is
published whenever the state of an airplay device has changed.
* `itunes-api/airplay_devices/:airplay_device_id/volume`, `45` - This is
published whenever the volume level of an airplay device is changed.

## API Docs

This is a quick overview of the service. Read [app.js](app.js) if you need more
info.
Expand Down
18 changes: 18 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var fs = require('fs')
var path = require('path')
var util = require('util')
var mqtt = require('mqtt');
var express = require('express')
var morgan = require('morgan')
var bodyParser = require('body-parser')
Expand All @@ -10,13 +11,18 @@ var osascript = require('osascript')
var airplay = require('./lib/airplay')
var parameterize = require('parameterize');

var config = require('./config/config.json');

var app = express()
app.use(bodyParser.urlencoded({ extended: false }))
app.use(express.static(path.join(__dirname, 'public')));

var logFormat = "'[:date[iso]] - :remote-addr - :method :url :status :response-time ms - :res[content-length]b'"
app.use(morgan(logFormat))

var mqttClient = mqtt.connect(config.mqtt);
var TOPIC_NAMESPACE = "itunes-api"

function getCurrentState(){
itunes = Application('iTunes');
playerState = itunes.playerState();
Expand Down Expand Up @@ -129,6 +135,11 @@ function getPlaylists(callback){
})
}

function publish(topic, message, options){
topic = TOPIC_NAMESPACE + "/" + topic
mqttClient.publish(topic, message, options);
}

app.get('/_ping', function(req, res){
res.send('OK');
})
Expand All @@ -139,12 +150,14 @@ app.get('/', function(req, res){

app.put('/play', function(req, res){
iTunes.play(function (error){
if (!error) publish('state', 'playing', {retain: true});
sendResponse(error, res)
})
})

app.put('/pause', function(req, res){
iTunes.pause(function (error){
if (!error) publish('state', 'paused', {retain: true});
sendResponse(error, res)
})
})
Expand All @@ -157,6 +170,7 @@ app.put('/playpause', function(req, res){

app.put('/stop', function(req, res){
iTunes.stop(function (error){
if (!error) publish('state', 'stopped', {retain: true});
sendResponse(error, res)
})
})
Expand All @@ -179,6 +193,7 @@ app.put('/volume', function(req, res){
console.log(error)
res.sendStatus(500)
}else{
if (!error) publish('volume', req.body.level, {retain: true});
sendResponse(error, res)
}
})
Expand Down Expand Up @@ -272,6 +287,7 @@ app.put('/airplay_devices/:id/on', function (req, res) {
console.log(error)
res.sendStatus(500)
}else{
publish('airplay_devices/' + req.params.id + '/state', 'on', {retain: true});
res.json(data)
}
})
Expand All @@ -283,6 +299,7 @@ app.put('/airplay_devices/:id/off', function (req, res) {
console.log(error)
res.sendStatus(500)
}else{
publish('airplay_devices/' + req.params.id + '/state', 'off', {retain: true});
res.json(data)
}
})
Expand All @@ -294,6 +311,7 @@ app.put('/airplay_devices/:id/volume', function (req, res) {
console.log(error)
res.sendStatus(500)
}else{
publish('airplay_devices/' + req.params.id + '/volume', req.body.level, {retain: true});
res.json(data)
}
})
Expand Down
8 changes: 8 additions & 0 deletions config/config.sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mqtt": {
"host": "127.0.0.1",
"port": "1883",
"username": "",
"password": ""
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"body-parser": "^1.12.4",
"local-itunes": "^0.3.0",
"osa": "2.2.0",
"parameterize": "^0.0.7"
"parameterize": "^0.0.7",
"mqtt": "^1.4.1"
}
}
8 changes: 8 additions & 0 deletions script/bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ mkdir -p log

npm install

if [ ! -f config/config.json ]
then
echo
echo "==> Creating your config. Please edit config/config.json."
echo
cp config/config.sample.json config/config.json
fi

echo "Finished setting up itunes-api! run it with script/server or install it with script/install."