AWS 上的 Demo server 停掉了,为此做个记录,以备后查。
借助AWS 官方的 IOT core sdk 可以模拟设备(假设是烟感器)进行TLS认证,和加密通讯数据。
方法一:借助Mqtt.fx 工具连接到AWS IOT core 平台上 。
获取设备端的 crt, 加密公钥和私钥,以及root.CA 具体方法参见“烟感器设备接入AWS IOT的一种方法(一)” 以下给出结果:
将上述文件下载到本地一个目录,然后倒入到mqtt.fx 中
mqtt.fx 进行connected 后,发送消息给IOT core ,IOT core端可以收到信息:
==========================================================================
方法二:将 aws-iot-device-sdk-embedded-C-master 安装在Ubuntu 上,如Mqtt.fx一样做相关连接配置后,可以连接到AWS IOT core 平台上 :(sdk的部分code : shadow_sample.c)
/*
* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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.
*/
/**
* @file shadow_sample.c
* @brief A simple connected window example demonstrating the use of Thing Shadow
*/
#include
#include
#include
#include
#include
#include
#include "aws_iot_config.h"
#include "aws_iot_log.h"
#include "aws_iot_version.h"
#include "aws_iot_mqtt_client_interface.h"
#include "aws_iot_shadow_interface.h"
/*!
* The goal of this sample application is to demonstrate the capabilities of shadow.
* This device(say Connected Window) will open the window of a room based on temperature
* It can report to the Shadow the following parameters:
* 1. temperature of the room (double)
* 2. status of the window (open or close)
* It can act on commands from the cloud. In this case it will open or close the window based on the json object "windowOpen" data[open/close]
*
* The two variables from a device's perspective are double temperature and bool windowOpen
* The device needs to act on only on windowOpen variable, so we will create a primitiveJson_t object with callback
The Json Document in the cloud will be
{
"reported": {
"temperature": 0,
"windowOpen": false
},
"desired": {
"windowOpen": false
}
}
*/
/* 新的jason格式
{
"reported": {
"ProductLifeCycle": 10000,
"SmokeErrState": 0,
"SmokeAlertFlag": 0,
"CODensity": 0,
"BatteryCapacity": 100,
"SmokeMuteFlag": 0
}
}
*/
#define ROOMTEMPERATURE_UPPERLIMIT 32.0f
#define ROOMTEMPERATURE_LOWERLIMIT 25.0f
#define STARTING_ROOMTEMPERATURE ROOMTEMPERATURE_LOWERLIMIT
//ProductLifeCycle
#define ROOMPRODUCTLIFECYCLE_UPPERLIMIT 10000.0
#define ROOMPRODUCTLIFECYCLE_LOWERLIMIT 1.0
#define STARTING_ROOMPRODUCTLIFECYCLE ROOMPRODUCTLIFECYCLE_LOWERLIMIT
//SmokeErrState
#define ROOMSMOKEERRSTATE_UPPERLIMIT 0
#define ROOMSMOKEERRSTATE_LOWERLIMIT 0
#define STARTING_ROOMSMOKEERRSTATE ROOMSMOKEERRSTATE_LOWERLIMIT
//SmokeAlertFlag value =[0,2,4,8]
#define ROOMSMOKEALERTFLAG_UPPERLIMIT 8
#define ROOMSMOKEALERTFLAG_LOWERLIMIT 0
#define STARTING_ROOMSMOKEALERTFLAG ROOMSMOKEALERTFLAG_LOWERLIMIT
//CODensity
#define ROOMCODENSITY_UPPERLIMIT 100
#define ROOMCODENSITY_LOWERLIMIT 0
#define STARTING_ROOMCODENSITY ROOMCODENSITY_LOWERLIMIT
//BatteryCapacity
#define ROOMBATTERYCAPATCITY_UPPERLIMIT 100.0
#define ROOMBATTERYCAPATCITY_LOWERLIMIT 1.0
#define STARTING_ROOMBATTERYCAPATCITY ROOMBATTERYCAPATCITY_LOWERLIMIT
//SmokeMuteFlag
#define ROOMSMOKEMUTEFLAG_UPPERLIMIT 0
#define ROOMSMOKEMUTEFLAG_LOWERLIMIT 0
#define STARTING_ROOMSMOKEMUTEFLAG ROOMSMOKEMUTEFLAG_LOWERLIMIT
#define MAX_LENGTH_OF_UPDATE_JSON_BUFFER 2000
// # define MAX_LENGTH_OF_UPDATE_JSON_BUFFER 200
static char certDirectory[PATH_MAX + 1] = "../../../certs";
#define HOST_ADDRESS_SIZE 255
static char HostAddress[HOST_ADDRESS_SIZE] = AWS_IOT_MQTT_HOST;
static uint32_t port = AWS_IOT_MQTT_PORT;
static uint8_t numPubs = 5;
static void simulateRoomTemperature(float *pRoomTemperature) {
static float deltaChange;
if(*pRoomTemperature >= ROOMTEMPERATURE_UPPERLIMIT) {
deltaChange = -0.5f;
} else if(*pRoomTemperature <= ROOMTEMPERATURE_LOWERLIMIT) {
deltaChange = 0.5f;
}
*pRoomTemperature += deltaChange;
}
// ProductLifeCycle
static void simulateRoomProductLifeCycle(float *pRoomProductLifeCycle) {
static float deltaChange;
if(*pRoomProductLifeCycle >= ROOMPRODUCTLIFECYCLE_UPPERLIMIT) {
deltaChange = -10;
} else if(*pRoomProductLifeCycle <= ROOMPRODUCTLIFECYCLE_LOWERLIMIT) {
deltaChange = 10;
}
*pRoomProductLifeCycle += deltaChange;
}
// SmokeErrState
static void simulateRoomSmokeErrState(int *pRoomSmokeErrState) {
static int deltaChange;
if(*pRoomSmokeErrState >= ROOMSMOKEERRSTATE_UPPERLIMIT) {
deltaChange = -0;
} else if(*pRoomSmokeErrState <= ROOMSMOKEERRSTATE_LOWERLIMIT) {
deltaChange = 0;
}
*pRoomSmokeErrState += deltaChange;
}
// SmokeAlertFlag
static void simulateRoomSmokeAlertFlag(int *pRoomSmokeAlertFlag) {
static int deltaChange;
if(*pRoomSmokeAlertFlag >= ROOMSMOKEALERTFLAG_UPPERLIMIT) {
deltaChange = -2;
} else if(*pRoomSmokeAlertFlag <= ROOMSMOKEALERTFLAG_LOWERLIMIT) {
deltaChange = 2;
}
*pRoomSmokeAlertFlag += deltaChange;
}
// CODensity
static void simulateRoomCODensity(float *pRoomCODensity) {
static float deltaChange;
if(*pRoomCODensity >= ROOMCODENSITY_UPPERLIMIT) {
deltaChange = -5.0;
} else if(*pRoomCODensity <= ROOMCODENSITY_LOWERLIMIT) {
deltaChange = 5.0;
}
*pRoomCODensity += deltaChange;
}
// BatteryCapacity
static void simulateRoomBatteryCapacity(float *pRoomBatteryCapacity) {
static float deltaChange;
if(*pRoomBatteryCapacity >= ROOMBATTERYCAPATCITY_UPPERLIMIT) {
deltaChange = -5.0;
} else if(*pRoomBatteryCapacity <= ROOMBATTERYCAPATCITY_LOWERLIMIT) {
deltaChange = 5.0;
}
*pRoomBatteryCapacity += deltaChange;
}
// SmokeMuteFlag
static void simulateRoomSmokeMuteFlag(int *pRoomSmokeMuteFlag) {
static int deltaChange;
if(*pRoomSmokeMuteFlag >= ROOMSMOKEMUTEFLAG_UPPERLIMIT) {
deltaChange = -0;
} else if(*pRoomSmokeMuteFlag <= ROOMSMOKEMUTEFLAG_LOWERLIMIT) {
deltaChange = 0;
}
*pRoomSmokeMuteFlag += deltaChange;
}
void ShadowUpdateStatusCallback(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status,
const char *pReceivedJsonDocument, void *pContextData) {
IOT_UNUSED(pThingName);
IOT_UNUSED(action);
IOT_UNUSED(pReceivedJsonDocument);
IOT_UNUSED(pContextData);
if(SHADOW_ACK_TIMEOUT == status) {
IOT_INFO("Update Timeout--");
} else if(SHADOW_ACK_REJECTED == status) {
IOT_INFO("Update RejectedXX");
} else if(SHADOW_ACK_ACCEPTED == status) {
IOT_INFO("Update Accepted !!");
}
}
void windowActuate_Callback(const char *pJsonString, uint32_t JsonStringDataLen, jsonStruct_t *pContext) {
IOT_UNUSED(pJsonString);
IOT_UNUSED(JsonStringDataLen);
if(pContext != NULL) {
IOT_INFO("Delta - Window state changed to %d", *(bool *) (pContext->pData));
}
}
void parseInputArgsForConnectParams(int argc, char **argv) {
int opt;
while(-1 != (opt = getopt(argc, argv, "h:p:c:n:"))) {
switch(opt) {
case 'h':
strncpy(HostAddress, optarg, HOST_ADDRESS_SIZE);
IOT_DEBUG("Host %s", optarg);
break;
case 'p':
port = atoi(optarg);
IOT_DEBUG("arg %s", optarg);
break;
case 'c':
strncpy(certDirectory, optarg, PATH_MAX + 1);
IOT_DEBUG("cert root directory %s", optarg);
break;
case 'n':
numPubs = atoi(optarg);
IOT_DEBUG("num pubs %s", optarg);
break;
case '?':
if(optopt == 'c') {
IOT_ERROR("Option -%c requires an argument.", optopt);
} else if(isprint(optopt)) {
IOT_WARN("Unknown option `-%c'.", optopt);
} else {
IOT_WARN("Unknown option character `\\x%x'.", optopt);
}
break;
default:
IOT_ERROR("ERROR in command line argument parsing");
break;
}
}
}
int main(int argc, char **argv) {
IoT_Error_t rc = FAILURE;
char JsonDocumentBuffer[MAX_LENGTH_OF_UPDATE_JSON_BUFFER];
size_t sizeOfJsonDocumentBuffer = sizeof(JsonDocumentBuffer) / sizeof(JsonDocumentBuffer[0]);
float temperature = 0.0;
float ProductLifeCycle = 1.0;
int SmokeErrState = 0;
//int SmokeAlertFlag = 0;
//float CODensity = 0;
float BatteryCapacity = 1.0;
int SmokeMuteFlag = 0;
int SmokeAlertFlag;
printf("please input SmokeAlertFlag value[0,1,2,4,8]:");
scanf("%d", &SmokeAlertFlag);
float CODensity;
printf("please input CODensity value(0--100):");
scanf("%f", &CODensity);
bool windowOpen = false;
jsonStruct_t windowActuator;
windowActuator.cb = windowActuate_Callback;
windowActuator.pData = &windowOpen;
windowActuator.dataLength = sizeof(bool);
windowActuator.pKey = "windowOpen";
windowActuator.type = SHADOW_JSON_BOOL;
jsonStruct_t temperatureHandler;
temperatureHandler.cb = NULL;
temperatureHandler.pKey = "temperature";
temperatureHandler.pData = &temperature;
temperatureHandler.dataLength = sizeof(float);
temperatureHandler.type = SHADOW_JSON_FLOAT;
jsonStruct_t ProductLifeCycleHandler;
ProductLifeCycleHandler.cb = NULL;
ProductLifeCycleHandler.pKey = "ProductLifeCycle";
ProductLifeCycleHandler.pData = &ProductLifeCycle;
ProductLifeCycleHandler.dataLength = sizeof(float);
ProductLifeCycleHandler.type = SHADOW_JSON_FLOAT;
jsonStruct_t SmokeErrStateHandler;
SmokeErrStateHandler.cb = NULL;
SmokeErrStateHandler.pKey = "SmokeErrState";
SmokeErrStateHandler.pData = &SmokeErrState;
SmokeErrStateHandler.dataLength = sizeof(int);
SmokeErrStateHandler.type = SHADOW_JSON_INT32;
jsonStruct_t SmokeAlertFlagHandler;
SmokeAlertFlagHandler.cb = NULL;
SmokeAlertFlagHandler.pKey = "SmokeAlertFlag";
SmokeAlertFlagHandler.pData = &SmokeAlertFlag;
SmokeAlertFlagHandler.dataLength = sizeof(int);
SmokeAlertFlagHandler.type = SHADOW_JSON_INT32;
jsonStruct_t CODensityHandler;
CODensityHandler.cb = NULL;
CODensityHandler.pKey = "CODensity";
CODensityHandler.pData = &CODensity;
CODensityHandler.dataLength = sizeof(float);
CODensityHandler.type = SHADOW_JSON_FLOAT;
jsonStruct_t BatteryCapacityHandler;
BatteryCapacityHandler.cb = NULL;
BatteryCapacityHandler.pKey = "BatteryCapacity";
BatteryCapacityHandler.pData = &BatteryCapacity;
BatteryCapacityHandler.dataLength = sizeof(float);
BatteryCapacityHandler.type = SHADOW_JSON_FLOAT;
jsonStruct_t SmokeMuteFlagHandler;
SmokeMuteFlagHandler.cb = NULL;
SmokeMuteFlagHandler.pKey = "SmokeMuteFlag";
SmokeMuteFlagHandler.pData = &SmokeMuteFlag;
SmokeMuteFlagHandler.dataLength = sizeof(int);
SmokeMuteFlagHandler.type = SHADOW_JSON_INT32;
char rootCA[PATH_MAX + 1];
char clientCRT[PATH_MAX + 1];
char clientKey[PATH_MAX + 1];
char CurrentWD[PATH_MAX + 1];
IOT_INFO("\nAWS IoT SDK Version %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
getcwd(CurrentWD, sizeof(CurrentWD));
snprintf(rootCA, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_ROOT_CA_FILENAME);
snprintf(clientCRT, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_CERTIFICATE_FILENAME);
snprintf(clientKey, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_PRIVATE_KEY_FILENAME);
IOT_DEBUG("rootCA %s", rootCA);
IOT_DEBUG("clientCRT %s", clientCRT);
IOT_DEBUG("clientKey %s", clientKey);
parseInputArgsForConnectParams(argc, argv);
// initialize the mqtt client
AWS_IoT_Client mqttClient;
ShadowInitParameters_t sp = ShadowInitParametersDefault;
sp.pHost = AWS_IOT_MQTT_HOST;
sp.port = AWS_IOT_MQTT_PORT;
sp.pClientCRT = clientCRT;
sp.pClientKey = clientKey;
sp.pRootCA = rootCA;
sp.enableAutoReconnect = false;
sp.disconnectHandler = NULL;
IOT_INFO("Shadow Init");
rc = aws_iot_shadow_init(&mqttClient, &sp);
if(SUCCESS != rc) {
IOT_ERROR("Shadow Connection Error");
return rc;
}
ShadowConnectParameters_t scp = ShadowConnectParametersDefault;
scp.pMyThingName = AWS_IOT_MY_THING_NAME;
scp.pMqttClientId = AWS_IOT_MQTT_CLIENT_ID;
scp.mqttClientIdLen = (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID);
IOT_INFO("Shadow Connect");
rc = aws_iot_shadow_connect(&mqttClient, &scp);
if(SUCCESS != rc) {
IOT_ERROR("Shadow Connection Error");
return rc;
}
/*
* Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h
* #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL
* #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
*/
rc = aws_iot_shadow_set_autoreconnect_status(&mqttClient, true);
if(SUCCESS != rc) {
IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc);
return rc;
}
rc = aws_iot_shadow_register_delta(&mqttClient, &windowActuator);
if(SUCCESS != rc) {
IOT_ERROR("Shadow Register Delta Error");
}
temperature = STARTING_ROOMTEMPERATURE;
ProductLifeCycle = STARTING_ROOMPRODUCTLIFECYCLE;
SmokeErrState = STARTING_ROOMSMOKEERRSTATE;
// SmokeAlertFlag = STARTING_ROOMSMOKEALERTFLAG; 设置默认报警值
// CODensity = STARTING_ROOMCODENSITY; 设置默认CODensity报警值
BatteryCapacity = STARTING_ROOMBATTERYCAPATCITY;
SmokeMuteFlag = STARTING_ROOMSMOKEMUTEFLAG;
// loop and publish a change in temperature
// NETWORK_ATTEMPTING_RECONNECT = 4 NETWORK_RECONNECTED = 3
//while(NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc) {
if(NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc) {
rc = aws_iot_shadow_yield(&mqttClient, 200);
if(NETWORK_ATTEMPTING_RECONNECT == rc) {
sleep(1);
// If the client is attempting to reconnect we will skip the rest of the loop.
//continue;
}
IOT_INFO("\n=======================================================================================\n");
// IOT_INFO("On Device: window state %s, BatteryCapacity state %.2f", windowOpen ? "true" : "false", BatteryCapacity);
printf("BatteryCapacity state %.2f \n", BatteryCapacity );
simulateRoomTemperature(&temperature);
simulateRoomProductLifeCycle(&ProductLifeCycle);
simulateRoomSmokeErrState(&SmokeErrState);
//simulateRoomSmokeAlertFlag(&SmokeAlertFlag);
//simulateRoomCODensity(&CODensity);
simulateRoomBatteryCapacity(&BatteryCapacity);
simulateRoomSmokeMuteFlag(&SmokeMuteFlag);
// loop and publish a change in BatteryCapacity
rc = aws_iot_shadow_init_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
if(SUCCESS == rc) {
/***
rc = aws_iot_shadow_add_reported(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 2, &temperatureHandler,
&windowActuator);
***/
rc = aws_iot_shadow_add_reported(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 6, &ProductLifeCycleHandler, &SmokeErrStateHandler, &SmokeAlertFlagHandler, &CODensityHandler, &BatteryCapacityHandler, &SmokeMuteFlagHandler);
//&windowActuator,
if(SUCCESS == rc) {
rc = aws_iot_finalize_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
if(SUCCESS == rc) {
IOT_INFO("Update Shadow: %s", JsonDocumentBuffer);
rc = aws_iot_shadow_update(&mqttClient, AWS_IOT_MY_THING_NAME, JsonDocumentBuffer,
ShadowUpdateStatusCallback, NULL, 4, true);
}
}
}
IOT_INFO("*****************************************************************************************\n");
sleep(1);
}
if(SUCCESS != rc) {
IOT_ERROR("An error occurred in the loop %d", rc);
}
IOT_INFO("Disconnecting");
rc = aws_iot_shadow_disconnect(&mqttClient);
if(SUCCESS != rc) {
IOT_ERROR("Disconnect error %d", rc);
}
return rc;
}
=================================================================
以上是设备接入AWS IOT的方法,下面说下如何通过IOT core 将设备端的报警事件推送到APP端(app信息,和短信,电话)
注: https://www.thorntech.com/2016/09/aws-iot-to-send-text-message-notifications/ (在AWS IOT core 上配置rule topic, 订阅,发送SNS SMS 给客户端 APP ) -----已经试验过
先上示意图:
设备(烟感器)在AWS IOT core 平台上对应的就是 Things ,然后依次创建 证书(device),策略,将策略附加到证书上,然后下载证书(device),将证书导入到设备中。 下面提供的是一个rule , iot core 根据 rule engine 做后续操作,比如执行Lambda 函数里面的逻辑。
==================================================================
Lambda 将 alert event 发给SNS ,由SNS 推送消息(app, 短信,电话)给用户端。
const http = require('http');
const https = require('https');
console.log('Loading function');
// Load the AWS SDK
var AWS = require("aws-sdk");
// Set up the code to call when the Lambda function is invoked
exports.handler = (event, context, callback) => {
// Load the message passed into the Lambda function into a JSON object
var eventText = JSON.stringify(event, null, 2);
// Log a message to the console, you can view this text in the Monitoring tab in the Lambda console or in the CloudWatch Logs console
console.log("Received event:", eventText);
var message_1_SES = "The smoke alarm! Please note that there may be a fire in your home!" ;
var message_1_SMS = "【The smoke alarm】"+ "\n" + " Please note that there may be a fire in your home! Please check your home immediately!" + "\n"+"\n"+" SmokeAlarm://open" ;
var message_1_APP = "SmokeAlarm!";
var jsonMessage_1_APP ={
"default": "This is the content of the push notification",
"APNS_SANDBOX": "{\"aps\":{\"alert\": {\"title\": \"SmokeAlarm\",\"body\": \"The SmokeAlarm! Please note that there may be a fire in your home!\"},\"sound\":\"default\"}}"
};
var message_2_SES = " The BatteryCapacity is Low ! " ;
var message_2_SMS = " The BatteryCapacity is Low !";
var jsonMessage_2_APP = {
"default": "This is the content of the push notification",
"APNS_SANDBOX": "{\"aps\":{\"alert\": {\"title\": \"BatteryCapacity\",\"body\": \" The BatteryCapacity is Low !\"},\"sound\":\"default\"}}"
};
var message_4_SES = " End of product life cycle! " ;
var message_4_SMS = " End of product life cycle! " ;
var jsonMessage_4_APP = {
"default": "This is the content of the push notification",
"APNS_SANDBOX": "{\"aps\":{\"alert\": {\"title\": \"ProductCycle\",\"body\": \" End of product life cycle!!\"},\"sound\":\"default\"}}"
};
var message_8_SES = "The CODensity Alarm! There is poisonous gas in your home, please open the window immediately and leave the indoor environment!" ;
var message_8_SMS = "【The CODensity Alarm】" + "\n" + "The CODensity Alarm! There is poisonous gas in your home, please open the window immediately and leave the indoor environment!" ;
var jsonMessage_8_APP = {
"default": "This is the content of the push notification",
"APNS_SANDBOX": "{\"aps\":{\"alert\": {\"title\": \"CODensityAlarm\",\"body\": \"The CODensity Alarm! There is poisonous gas in your home, please open the window immediately and leave the indoor environment!!\"},\"badge\":1,\"sound\":\"default\"}}"
};
var body = '1539765278 6613241512949142455 ';
// var json = JSON.stringify(body);
// var access_token = '14_HTUJQ4zcPn3Zc6uUAO0Yqo4Rv6nDhcch8n5F5cMF9yWEcSx5dsuXb1qG1DZTlJauvGnfSy8RP1ojQkx4YoDRzzslJDNLaQMmP7QWG3WwBTbo12qOvL9K7c_IScNG4EnSR9APP4OQFU1ZSqrDVQYaABAPKS';
var postRequest = {
host: 'ec2-54-190-199-48.us-west-2.compute.amazonaws.com',
path: '/wx',
port: 80,
method: 'POST',
// body:body,
headers: {
'Cookie': "cookie",
'Content-Type': 'text/xml',
// 'Content-Type': 'application/json;charset=UTF-8',
'Content-Length': Buffer.byteLength(body)
}
};
var buffer = "";
var postdata = "";
var req = http.request( postRequest, function( res ) {
console.log( res.statusCode );
var buffer = "";
res.on ( "postdata", function( postdata ) {
buffer = buffer + postdata;
} );
res.on( "end", function( postdata ) {
console.log( buffer ); } );
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write( body );
req.end();
console.log("Message to send: " + message_1_SES);
// Create an SNS object
var sns = new AWS.SNS();
// Populate the parameters for the publish operation
var SmokeAlertFlag_1_SES = {
Message: message_1_SES,
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo"
};
var SmokeAlertFlag_1_SMS = {
Message: message_1_SMS,
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo_SMS"
};
var SmokeAlertFlag_1_APP = {
Message: JSON.stringify(jsonMessage_1_APP),
// Message: payload,
MessageStructure: "json",
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo_APP"
};
var SmokeAlertFlag_2_SES = {
Message: message_2_SES,
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo"
};
var SmokeAlertFlag_2_SMS = {
Message: message_2_SMS,
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo_SMS"
};
var SmokeAlertFlag_2_APP = {
Message: JSON.stringify(jsonMessage_2_APP),
MessageStructure: "json",
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo_APP"
};
var SmokeAlertFlag_4_SES = {
Message: message_4_SES,
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo"
};
var SmokeAlertFlag_4_SMS = {
Message: message_4_SMS,
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo_SMS"
};
var SmokeAlertFlag_4_APP = {
Message: JSON.stringify(jsonMessage_4_APP),
MessageStructure: "json",
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo_APP"
};
var SmokeAlertFlag_8_SES = {
Message: message_8_SES,
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo"
};
var SmokeAlertFlag_8_SMS = {
Message: message_8_SMS,
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo_SMS"
};
var SmokeAlertFlag_8_APP = {
Message: JSON.stringify(jsonMessage_8_APP),
MessageStructure: "json",
TopicArn: "arn:aws:sns:us-west-2:714007299995:SmokeSensor_Demo_APP"
};
if(event.state.reported.SmokeAlertFlag == 1){
sns.publish(SmokeAlertFlag_1_SES, context.done);
sns.publish(SmokeAlertFlag_1_SMS, context.done);
sns.publish(SmokeAlertFlag_1_APP, context.done);
// http.postMessage (SmokeAlertFlag_1_SES,'http://ec2-54-190-199-48.us-west-2.compute.amazonaws.com/wx');
}else if(event.state.reported.SmokeAlertFlag == 2){
sns.publish(SmokeAlertFlag_2_SES, context.done);
sns.publish(SmokeAlertFlag_2_SMS, context.done);
sns.publish(SmokeAlertFlag_2_APP, context.done);
}else if(event.state.reported.SmokeAlertFlag == 4){
sns.publish(SmokeAlertFlag_4_SES, context.done);
sns.publish(SmokeAlertFlag_4_SMS, context.done);
sns.publish(SmokeAlertFlag_4_APP, context.done);
}else if(event.state.reported.SmokeAlertFlag == 8){
sns.publish(SmokeAlertFlag_8_SES, context.done);
sns.publish(SmokeAlertFlag_8_SMS, context.done);
sns.publish(SmokeAlertFlag_8_APP, context.done);
}
};
==========================================================================
Lambda 中有 接入微信硬件平台的code, 用来发送Smoke Alert Event 给微信公众号,并由公众号转发给关注该微信公众号的终端微信用户。
其架构如下:
=========================================================================
ec2 server 上的关键code:
handle.py
# -*- coding: utf-8 -*-
#python 27
#filename: handle.py
import hashlib
import web
import reply
import receive
import urllib2
import urllib
import json
class Handle(object):
def GET(self):
try:
data = web.input()
if len(data) == 0:
return "hello, this is handle view"
signature = data.signature
timestamp = data.timestamp
nonce = data.nonce
echostr = data.echostr
token = "helxxxaws" #请按照公众平台官网\基本配置中信息填写
list = [token, timestamp, nonce]
list.sort()
sha1 = hashlib.sha1()
map(sha1.update, list)
hashcode = sha1.hexdigest()
print "handle/GET func: hashcode, signature: ", hashcode, signature
if hashcode == signature:
return echostr
else:
return ""
except Exception, Argument:
return Argument
class Handle(object):
def POST(self):
try:
webData = web.data()
print "Handle Post webdata is ", webData
htmlurl='https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential' #grant_type为固定值
htmldata={
'appid':'wxc5ad96e7xxxxxxx2',
'secret':'246fa64a45f486xxxxxxxxxxd65ff453'
}
htmldata=urllib.urlencode(htmldata)
html=urllib.urlopen(htmlurl,htmldata) #>
html=html.read()
access_token=json.loads(html)['access_token']
print "access_token=",access_token
#后台打日志
recMsg = receive.parse_xml(webData)
if isinstance(recMsg, receive.Msg) and recMsg.MsgType == 'text':
url=('https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s'%access_token)
# url=base_url + urllib.urlencode(access_token)
body = {
"touser": "oTb0x5hvi2TRxxxxxjgOYZUgVQ",
"msgtype": "text",
"text": {
"content": "The smoke alarm! Please note that there may be a fire in your home!"
}
}
jdata = json.dumps(body)
headers = {'Content-Type': 'application/json'}
# data=urllib.urlencode(body)
request = urllib2.Request(url, jdata)
print "request=",request
response = urllib2.urlopen(request)
print"response=", response.read()
return response.read()
toUser = recMsg.FromUserName
fromUser = recMsg.ToUserName
content = "test"
replyMsg = reply.TextMsg(toUser, fromUser, content)
print "reply.textmsg=",replyMsg
return replyMsg.send()
else:
print "暂且不处理"
return "success"
except Exception, Argment:
return Argment
========================================================================
微信端 接收到的信息: