node-hue-api
Version:
Philips Hue API Library for Node.js
115 lines (114 loc) • 4.17 kB
JavaScript
import { model, time } from '@peter-murray/hue-bridge-model';
import { extractUpdatedAttributes, parseErrors, wasSuccessful } from '../../../util';
import { ApiEndpoint } from './ApiEndpoint';
import { ScheduleIdPlaceholder } from '../../placeholders/ScheduleIdPlaceholder';
import { ApiError } from '../../../ApiError';
const SCHEDULE_ID_PLACEHOLDER = new ScheduleIdPlaceholder();
const instanceChecks = model.instanceChecks;
const schedulesApi = {
getAll: new ApiEndpoint()
.get()
.acceptJson()
.uri('/<username>/schedules')
.pureJson()
.postProcess(buildSchedulesResult),
createSchedule: new ApiEndpoint()
.post()
.acceptJson()
.uri('/<username>/schedules')
.pureJson()
.payload(buildSchedulePayload)
.postProcess(buildCreateScheduleResult),
getScheduleAttributes: new ApiEndpoint()
.get()
.uri('/<username>/schedules/<id>')
.placeholder(SCHEDULE_ID_PLACEHOLDER)
.acceptJson()
.pureJson()
.postProcess(buildSchedule),
setScheduleAttributes: new ApiEndpoint()
.put()
.uri('/<username>/schedules/<id>')
.placeholder(SCHEDULE_ID_PLACEHOLDER)
.acceptJson()
.payload(buildUpdateSchedulePayload)
.pureJson()
.postProcess(extractUpdatedAttributes),
deleteSchedule: new ApiEndpoint()
.delete()
.acceptJson()
.uri('/<username>/schedules/<id>')
.placeholder(SCHEDULE_ID_PLACEHOLDER)
.pureJson()
.postProcess(wasSuccessful),
};
export { schedulesApi };
function buildSchedulesResult(result) {
let schedules = [];
Object.keys(result).forEach(function (id) {
schedules.push(model.createFromBridge('schedule', id, result[id]));
});
return schedules;
}
function buildSchedule(data, requestParameters) {
const id = SCHEDULE_ID_PLACEHOLDER.getValue(requestParameters);
return model.createFromBridge('schedule', id, data);
}
function buildSchedulePayload(parameters) {
const schedule = parameters.schedule;
if (!schedule) {
throw new ApiError('Schedule to create must be provided');
}
else if (!instanceChecks.isScheduleInstance(schedule)) {
throw new ApiError('You must provide a valid instance of a Schedule to be created');
}
const payload = getSchedulePayload(parameters.username, schedule);
return {
type: 'application/json',
body: payload
};
}
function buildUpdateSchedulePayload(parameters) {
const schedule = parameters.schedule;
if (!schedule) {
throw new ApiError('Schedule to update must be provided');
}
else if (!instanceChecks.isScheduleInstance(schedule)) {
throw new ApiError('You must provide a valid instance of a Schedule when updating');
}
const payload = getSchedulePayload(parameters.username, schedule);
// Extract only the values we can update on a schedule
const body = {};
['name', 'description', 'command', 'localtime', 'status', 'autodelete'].forEach(key => {
if (payload[key] !== null) {
body[key] = payload[key];
}
});
return {
type: 'application/json',
body: body
};
}
function buildCreateScheduleResult(result) {
const hueErrors = parseErrors(result); //TODO not sure if this still gets called as the request handles some of this
if (hueErrors) {
throw new ApiError(`Error creating group: ${hueErrors[0].description}`, hueErrors[0]);
}
const id = result[0].success.id;
return {
id: SCHEDULE_ID_PLACEHOLDER.getValue({ id: id })
};
}
function getSchedulePayload(username, schedule) {
const payload = schedule.getHuePayload();
if (time.isRecurring(payload.localtime)) {
// autodelete does not apply to recurring schedules (as specified in the localtime)
delete payload.autodelete;
}
// Fix the address from the action to start with "/api/{username}"
const address = payload.command.address;
if (!/^\/api\//.test(address)) {
payload.command.address = `/api/${username}${address}`;
}
return payload;
}