User Tools

Site Tools


action_http
http.lua
--
-- Copyright (C) 2018 CurlyMo & Niek
--
-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at http://mozilla.org/MPL/2.0/.
--
 
local M = {}
 
function M.check(parameters)
	if parameters['DEVICE'] ~= nil then 
		if #parameters['DEVICE']['value'] ~= 1 or parameters['DEVICE']['value'][2] ~= nil then
			error("http action \"DEVICE\" only takes one argument");
		end
		local devname = parameters['DEVICE']['value'][1]
		local devobj = pilight.config.device(devname);
		if devobj == nil then
			error("http action device \"" .. devname .. "\" does not exist");
		end
		if devobj.getLabel == nil or devobj.getColor == nil then
			error("http action device \"" .. devname .. "\" isn't a generic_label device");
		end
		if devobj.getColor() == "busy" then -- reset busy state
			local async = pilight.async.thread();
			local data = async.getUserdata();
			data['device'] = devname;
			data['old_data'] = devobj.getLabel();
			data['new_state'] = "ready"
			async.setCallback("thread");
			async.trigger();
		end
	end
 
	if parameters['GET'] == nil and parameters['POST'] == nil then
		error("http action is missing a \"GET\" or \"POST\" statement");
	end
 
	if parameters['GET'] ~= nil and parameters['POST'] ~= nil then
			error("http action cannot have \"GET\" and \"POST\" statements at the same time");
	end
 
	if parameters['GET'] ~= nil then
		if parameters['MIMETYPE'] ~= nil then
			error("http action \"GET\" doesn't take a \"MIMETYPE\" statement");
		end
 
		if parameters['DATA'] ~= nil then
			error("http action \"GET\" doesn't take a \"DATA\" statement");
		end
 
		if (#parameters['GET']['value'] ~= 1 or parameters['GET']['value'][2] ~= nil) then
			error("http action \"GET\" only takes one argument");
		end
	end
 
	if parameters['POST'] ~= nil then
		if parameters['MIMETYPE'] == nil then
			error("http action \"POST\" request requires a \"MIMETYPE\" statement");
		end
 
		if parameters['DATA'] == nil then
			error("http action \"POST\" request requires a \"DATA\" statement");
		end
 
		if (#parameters['POST']['value'] ~= 1 or parameters['POST']['value'][2] ~= nil) then
			error("http action \"POST\" only takes one argument");
		end
 
		if (#parameters['MIMETYPE']['value'] ~= 1 or parameters['MIMETYPE']['value'][2] ~= nil) then
			error("http action \"MIMETYPE\" only takes one argument");
		end
 
		if (#parameters['DATA']['value'] ~= 1 or parameters['DATA']['value'][2] ~= nil) then
			error("http action \"DATA\" only takes one argument");
		end
	end
 
	return 1;
end
 
function M.callback(http) 
	local data = http.getUserdata();
	if data['device'] ~= nil then
		local devname = data['device'];
		local devobj = pilight.config.device(devname);
		local info = "code=" .. tostring(http.getCode()) .. "&size=" .. tostring(http.getSize())
		if string.len(http.getMimetype()) > 0 then
			info = info .."&mimetype=" .. http.getMimetype()
		end
 
		if devobj.setColor(info) == false then
			error("http action device \"" .. devname .. "\" color could not be set to  \"" .. info .. "\"")
		end
		local label = data['old_data'];
		if http.getCode() == 200 then
			label = http.getData();
		end
		if devobj.setLabel(label) == false then
			error("http action device \"" .. devname .. "\" label could not be set to  \"" .. label .. "\"")
		end
 
		devobj.send();
	end 
 
	if http.getCode() == 200 then
		error("http action calling ".. http.getUrl() .. " succeeded, received \"" .. http.getData() .. "\"");
	else
		error("http action calling ".. http.getUrl() .. " failed with code " .. tostring(http.getCode()));
	end
end
 
function M.thread(thread) -- only set color to new state, preserve old data
	local data = thread.getUserdata();
	local devname = data['device'];
	local devobj = pilight.config.device(devname);
 
	if devobj.setColor(data['new_state']) == false then
		error("http action device \"" .. devname .. "\" color could not be set to \" .. data['new_state'].. \"")
	end
 
	if devobj.setLabel(data['old_data']) == false then
		error("http action device \"" .. devname .. "\" label could not be set to \"" .. data['old_data'] .. "\"")
	end
 
	devobj.send();
end
 
function M.run(parameters)
	local httpobj = pilight.network.http();
	httpobj.setCallback("callback");
	local data = httpobj.getUserdata();
	data['device'] = nil;
 
	if parameters['DEVICE'] ~= nil then
		local devname = parameters['DEVICE']['value'][1];
		data['device'] = devname;
		local devobj = pilight.config.device(devname);
		if devobj.getColor() == "busy" then
			error("http action previous request for device \"" .. devname .. "\" in progress, request skipped!")
		end
 
		local old_state = devobj.getColor();
		local new_state = nil;
		local old_data = devobj.getLabel();
		data['old_data'] = old_data;
 
		if old_state ~= nil then
			local async = pilight.async.thread();
			local data = async.getUserdata();
			data['device'] = devname;
			data['old_data'] = old_data;
			data['new_state'] = "busy"
 
			async.setCallback("thread");
			async.trigger();
		end
	end
 
	if parameters['GET'] ~= nil then
		httpobj.setUrl(parameters['GET']['value'][1]);
		httpobj.setMimetype("");
		httpobj.get();
	else
		httpobj.setUrl(parameters['POST']['value'][1]);
		httpobj.setMimetype(parameters['MIMETYPE']['value'][1]);
		httpobj.setData(parameters['DATA']['value'][1]);
		httpobj.post();
	end
 
	return 1;
 
end
 
function M.parameters()
	return "POST", "GET", "DEVICE", "MIMETYPE", "DATA";
end
 
function M.info()
	return {
		name = "http",
		version = "0.3",
		reqversion = "8.1.1",
		reqcommit = "0"
	}
end
 
return M;
action_http.txt · Last modified: 2018/08/15 14:28 by Niek