===== GUIDA PER LE PUSH TRIGGHERATE DA postgreSQL DB =====
==== 0. push con Curl all'ACS app da server ====
=== Registration fatta da device android ===
== Login ==
Req: POST /v1/users/login.json
Resp:
Request Time 2014-11-06T14:28:40.514Z
Request Name POST /v1/users/login.json
Response Status 200
Parameters {"version":"v1","action":"create","controller":"user_sessions","suppress_response_codes":"true","ti_analytics":"{\"mid\":\"68c2554c54f77013\",\"app_version\":\"1.0\",\"platform\":\"android\"}","key":"XC6OWeoFQGEgP6Xtfb9V0mbF9oqgicjT","format":"json","password":"[FILTERED]","login":"APA91bFrI1834PnWi2drJJbWNdwJqLKh9bf28ncmrhGQkPELFL7zNT6feYtMqLzRnD3pV7OykE3xuer4jBufSBJTPmM3JLhjqJdBg7wR3eRHkvN76-hp2D1JgWgQHgR5N1vJqEBVZYkAI4RYHPAV5NQz1APBSoGozJPsUXhifwdWxz0ftxco5KQ"}
User Agent Appcelerator Titanium/3.3.0 (XT1032; Android API Level: 19; it-IT;)
Source IP 2.38.75.101
Response Size 648 bytes
== Registration ==
Req: POST /v1/push_notification/subscribe.json
Resp:
Request Time 2014-11-06T14:28:42.063Z
Request Name POST /v1/push_notification/subscribe.json
Response Status 200
Parameters {"version":"v1","channel":"honeywell.userapp","type":"android","device_token":"APA91bFrI1834PnWi2drJJbWNdwJqLKh9bf28ncmrhGQkPELFL7zNT6feYtMqLzRnD3pV7OykE3xuer4jBufSBJTPmM3JLhjqJdBg7wR3eRHkvN76-hp2D1JgWgQHgR5N1vJqEBVZYkAI4RYHPAV5NQz1APBSoGozJPsUXhifwdWxz0ftxco5KQ","action":"subscribe","controller":"push_notification","suppress_response_codes":"true","ti_analytics":"{\"mid\":\"68c2554c54f77013\",\"app_version\":\"1.0\",\"platform\":\"android\"}","key":"XC6OWeoFQGEgP6Xtfb9V0mbF9oqgicjT","format":"json","_session_id":"ABVNeeMJmfygK5oGDlvG1d171bI"}
User Agent Appcelerator Titanium/3.3.0 (XT1032; Android API Level: 19; it-IT;)
Source IP 2.38.75.101
Response Size 73 bytes
=== Push ===
Req: curl -b cookies.txt -c cookies.txt -X POST -F "channel=honeywell.userapp" -F "totokens=APA91bFrI1834PnWi2drJJbWNdwJqLKh9bf28ncmrhGQkPELFL7zNT6feYtMqLzRnD3pV7OykE3xuer4jBufSBJTPmM3JLhjqJdBg7wR3eRHkvN76-hp2D1JgWgQHgR5N1vJqEBVZYkAI4RYHPAV5NQz1APBSoGozJPsUXhifwdWxz0ftxco5KQ" -F "payload=prova_acs" "https://api.cloud.appcelerator.com/v1/push_notificationnotify_tokens.json?key=XC6OWeoFQGEgP6Xtfb9V0mbF9oqgicjT&pretty_json=true"
Resp:
Request Time 2014-11-06T14:56:57.648Z
Request Name POST /v1/push_notification/notify_tokens.json
Response Status 200
Parameters {"payload":"prova_acs","version":"v1","channel":"honeywell.userapp","action":"notify_tokens","controller":"push_notification","key":"XC6OWeoFQGEgP6Xtfb9V0mbF9oqgicjT","format":"json","to_tokens":"APA91bFrI1834PnWi2drJJbWNdwJqLKh9bf28ncmrhGQkPELFL7zNT6feYtMqLzRnD3pV7OykE3xuer4jBufSBJTPmM3JLhjqJdBg7wR3eRHkvN76-hp2D1JgWgQHgR5N1vJqEBVZYkAI4RYHPAV5NQz1APBSoGozJPsUXhifwdWxz0ftxco5KQ","pretty_json":"true"}
User Agent curl/7.26.0
Source IP 2.38.75.101
Response Size 64 bytes
Per una guida sulle push, vedere http://docs.befair.it/doku.php?id=push_notifications:appcelerator
=== PROVA CON urllib, urllib2, cookielib.CookieJar ===
**doc** http://stackoverflow.com/questions/3334809/python-urllib2-how-to-send-cookie-with-urlopen-request
==== 1. creare funzione per push con plpythonu (plpython2) ====
To install PL/Python in a particular database:
1. apt-get install postgresql-plpython if necessary
2. form shell, createlang -U postgres -d push plpythonu
Since plpythonu is untrusted, onlu superusers can use it.
Create file with CREATE FUNCTION
Apply sql to db
ACS Login:
CREATE OR REPLACE FUNCTION push_notifications_login(url text, login text, password text)
RETURNS text AS
$BODY$
import urllib, urllib2
from cookielib import CookieJar
cj = CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
login_values = {'login': login,'password' : password}
login_data = urllib.urlencode(login_values)
login_resp = opener.open(url,login_data)
return login_resp.getcode()
$BODY$
LANGUAGE plpythonu VOLATILE
COST 100;
ALTER FUNCTION push_notifications_login(text, text, text)
OWNER TO postgres;
ACS push:
CREATE OR REPLACE FUNCTION push_notifications_notify(login_url text, login text, password text, push_url text, channel text, token text, payload text)
RETURNS text AS
$BODY$
import urllib, urllib2
from cookielib import CookieJar
cj = CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
login_values = {'login': login,'password' : password}
login_data = urllib.urlencode(login_values)
login_resp = opener.open(login_url,login_data)
if login_resp.getcode() == '200':
notify_values = {'channel' : channel, 'to_tokens':token,'payload':payload}
notify_data = urllib.urlencode(notify_values)
notify_resp = opener.open(push_url,notify_data)
if notify_restp.getcode() == '200':
return True
else:
return False
$BODY$
LANGUAGE plpythonu VOLATILE
COST 100;
ALTER FUNCTION push_notifications_notify(text, text, text, text, text, text, text)
OWNER TO postgres;
==== 2. push con plpythonu (plpython2) da shell postgresql ====
SLELECT[function_name]
ESEMPI:
SELECT push_notifications_login(url := 'https://api.cloud.appcelerator.com/v1/users/login.json?key=XC6OWeoFQGEgP6Xtfb9V0mbF9oqgicjT&pretty_json=true' , login := 'user', password := 'user');
SELECT push_notifications_notify(url := 'https://api.cloud.appcelerator.com/v1/push_notification/notify_tokens.json?key=XC6OWeoFQGEgP6Xtfb9V0mbF9oqgicjT&pretty_json=true', channel := 'honeywell.userapp', token := 'APA91bFrI1834PnWi2drJJbWNdwJqLKh9bf28ncmrhGQkPELFL7zNT6feYtMqLzRnD3pV7OykE3xuer4jBufSBJTPmM3JLhjqJdBg7wR3eRHkvN76-hp2D1JgWgQHgR5N1vJqEBVZYkAI4RYHPAV5NQz1APBSoGozJPsUXhifwdWxz0ftxco5KQ', payload := 'prova_acs_questions');
==== 3. creare trigger pl/pgsql ====
CREATE OR REPLACE FUNCTION notify_status_update() RETURNS trigger AS $notify_status_update$
DECLARE
app_key text;
channel text;
token text;
payload text;
login_url text;
notify_url text;
BEGIN
EXECUTE format('SELECT app_key FROM honeywell_heatpump_token WHERE heat_pump_id=$1;') USING OLD.id INTO app_key;
EXECUTE format('SELECT channel FROM honeywell_channel WHERE id=$1;') USING OLD.id INTO channel;
EXECUTE format('SELECT token FROM honeywell_heatpump_token WHERE heat_pump_id=$1;') USING OLD.id INTO token;
payload := 'status turned to' || cast(NEW.status as text);
login_url := 'https://api.cloud.appcelerator.com/v1/users/login.json?key=' || app_key || '&pretty_json=true';
notify_url := 'https://api.cloud.appcelerator.com/v1/push_notification/notify_tokens.json?key=' || app_key || '&pretty_json=true';
-- EXECUTE format('SELECT push_notifications_login(url := $1, login := ''admin'', password := ''admin'')'
) USING login_url;
EXECUTE format('SELECT push_notifications_notify(login_url := $1, login := $2, password := $3, push_url := $4, channel := $5, token := $6, payload := $7);'
) USING login_url, login, password, notify_url, channel, token, payload;
END;
$notify_status_update$ LANGUAGE plpgsql;
CREATE TRIGGER notify_status_update BEFORE UPDATE ON honeywell_heatpump
FOR EACH ROW EXECUTE PROCEDURE notify_status_update()
==== 4. agganciare trigger al server ====
==== 5. ESEMPIO ====
Target database:
Lista delle relazioni
Schema | Nome | Tipo | Proprietario
--------+---------------------------------+----------+--------------
public | honeywell_channel | tabella | matteo
public | honeywell_channel_id_seq | sequenza | matteo
public | honeywell_heatpump | tabella | matteo
public | honeywell_heatpump_id_seq | sequenza | matteo
public | honeywell_heatpump_token | tabella | matteo
public | honeywell_heatpump_token_id_seq | sequenza | matteo
CREATE TABLE "honeywell_heatpump" ("id" SERIAL NOT NULL PRIMARY KEY ,"heat" varchar(32), "status" integer NOT NULL);
CREATE TABLE "honeywell_channel" ("id" SERIAL NOT NULL PRIMARY KEY, "channel" varchar(64));
CREATE TABLE "honeywell_heatpump_token" ("id" SERIAL NOT NULL PRIMARY KEY ,"heat_pump_id" integer NOT NULL REFERENCES "honeywell_heatpump" ("id"), "token" varchar(256),"app_key" varchar(64),"channel" integer NOT NULL REFERENCES "honeywell_channel" ("id"));
Define functions as in section 2 and 3.
INSERT INTO honeywell_heatpump (heat,status) VALUES ('heat1',0);
INSERT INTO honeywell_channel (channel) VALUES ('honeywell.userapp');
INSERT INTO honeywell_heatpump_token (heat_pump_id,token,app_key,channel) VALUES ((select id from honeywell_heatpump where id = 1),'APA91bFrI1834PnWi2drJJbWNdwJqLKh9bf28ncmrhGQkPELFL7zNT6feYtMqLzRnD3pV7OykE3xuer4jBufSBJTPmM3JLhjqJdBg7wR3eRHkvN76-hp2D1JgWgQHgR5N1vJqEBVZYkAI4RYHPAV5NQz1APBSoGozJPsUXhifwdWxz0ftxco5KQ','XC6OWeoFQGEgP6Xtfb9V0mbF9oqgicjT',(select id from honeywell_channel where id = 1));
UPDATE honeywell_heatpump SET status = 1;
==== 5.1 ESEMPIO 2 ====
Esempio di trigger su una tabella di uno schema.
=== Creazione funzione da triggherare ===
CREATE OR REPLACE FUNCTION notify_status_update() RETURNS trigger AS $notify_status_update$
DECLARE
app_key text := 'lEJ3oT6DG92XYbx0pH3wzL2kOdphFr7y';
channel text := TG_TABLE_SCHEMA;
token text := 'everyone';
payload text;
login_url text := 'https://api.cloud.appcelerator.com/v1/users/login.json?key=' || app_key ;
notify_url text := 'https://api.cloud.appcelerator.com/v1/push_notification/notify_tokens.json?key=' || app_key ;
OLD RECORD;
TABLE_FULLNAME text := '"' || TG_TABLE_SCHEMA || '"."' || TG_TABLE_NAME || '"';
board_label text;
BEGIN
RAISE NOTICE 'channel: %', channel;
SELECT label FROM acs_service.chamber WHERE dbname = TG_TABLE_SCHEMA INTO board_label;
SELECT * FROM get_last_reliable_var_row(TABLE_FULLNAME,NEW.id) AS row_out (
id integer,
variablename character varying,
val character varying,
statuscode character varying,
"timestamp" integer,
timestampe integer,
started integer,
sampletime integer,
idactor integer
) INTO OLD;
RAISE NOTICE 'OLD.val: % NEW.val: %', OLD.val, NEW.val;
-- Do nothing if only statuscode is changed...
IF OLD.val != NEW.val THEN
IF NEW.val::float <> 0 THEN
payload := board_label || ' is faulting: error ' || NEW.val;
ELSE
payload := board_label || ' no faulting anymore';
END IF;
RAISE NOTICE 'login_url: %', login_url;
EXECUTE format('SELECT push_notifications_login(url := $1, login := ''admin'', password := ''admin'')'
) USING login_url;
EXECUTE format('SELECT push_notifications_notify(url := $1,channel := $2,token := $3,payload := $4);'
) USING notify_url, channel, token, payload;
RAISE NOTICE 'notify_url: % channel: % token: % payload: %', notify_url, channel, token, payload;
END IF;
RETURN NEW;
END;
$notify_status_update$ LANGUAGE plpgsql;
=== Creazione del trigger (DROP preventivo se necessario) ===
La CREATE è fatta su un AFTER INSERT perchè ad un update su una righa corrisponde, in realtà, una CREATE nella tabella.
drop trigger notify_status_update ON [RELATION];
CREATE TRIGGER notify_status_update AFTER INSERT ON [RELATION]
FOR EACH ROW WHEN ( NEW.statuscode NOT LIKE '%FF__') EXECUTE PROCEDURE notify_status_update();
Ad esempio: "KIT-ff-1e-c0-13-d4-0c"."v1"
==== GET LAST ROW BEFORE INSERT ====
Funzione per prendere l'ultima row valida nella tabella.
Dato che siamo in una AFTER INSERT, l'ultima row valida è in realtà quella corrente.
Per questo, dalla select viene esclusa l'ultima riga appena inserita (quella con id = NEW.id)
CREATE OR REPLACE FUNCTION get_last_reliable_var_row(tablename text, id integer)
RETURNS RECORD AS
$BODY$
DECLARE
last_row RECORD;
BEGIN
EXECUTE 'SELECT * FROM ' || tablename || ' WHERE statuscode NOT LIKE '
|| quote_literal('%%%%FF__') || ' AND id NOT IN (' || id || ') ORDER BY timestampe DESC LIMIT 1'
INTO last_row;
RETURN last_row;
END;
$BODY$ LANGUAGE plpgsql VOLATILE
COST 100;