Merge pull request #174 from charithag/master

Update agent code and analytics scripts. Fixed bugs
merge-requests/1/head
inoshperera 9 years ago committed by GitHub
commit 11c5056b99

@ -23,7 +23,7 @@
CREATE TEMPORARY TABLE DevicerelayData USING CarbonAnalytics OPTIONS(tableName "ORG_WSO2_IOT_DEVICES_relay"); CREATE TEMPORARY TABLE DevicerelayData USING CarbonAnalytics OPTIONS(tableName "ORG_WSO2_IOT_DEVICES_relay");
CREATE TEMPORARY TABLE DevicerelaySummaryData USING CarbonAnalytics OPTIONS (tableName "DEVICE_relay_SUMMARY", CREATE TEMPORARY TABLE DevicerelaySummaryData USING CarbonAnalytics OPTIONS (tableName "DEVICE_relay_SUMMARY",
schema "relay FLOAT, deviceType STRING -i, deviceId STRING -i, owner STRING -i, time LONG -i",primaryKeys schema "relay BOOLEAN, deviceType STRING -i, deviceId STRING -i, owner STRING -i, time LONG -i",primaryKeys
"deviceType, deviceId, owner, time"); "deviceType, deviceId, owner, time");
insert into table DevicerelaySummaryData select relay, meta_deviceType as deviceType, meta_deviceId as deviceId, insert into table DevicerelaySummaryData select relay, meta_deviceType as deviceType, meta_deviceId as deviceId,

@ -24,7 +24,7 @@
"payloadData": [ "payloadData": [
{ {
"name": "relay", "name": "relay",
"type": "BOOLEAN" "type": "BOOL"
} }
] ]
} }

@ -7,10 +7,10 @@
/* define streams/tables and write queries here ... */ /* define streams/tables and write queries here ... */
@Import('org.wso2.iot.watertank:1.0.0') @Import('org.wso2.iot.watertank:1.0.0')
define stream watertank (meta_owner string, meta_deviceId string, relay float, waterlevel float); define stream watertank (meta_owner string, meta_deviceId string, relay bool, waterlevel float);
@Export('org.wso2.iot.devices.relay:1.0.0') @Export('org.wso2.iot.devices.relay:1.0.0')
define stream relay (meta_owner string, meta_deviceType string, meta_deviceId string, meta_time long, relay float); define stream relay (meta_owner string, meta_deviceType string, meta_deviceId string, meta_time long, relay bool);
@Export('org.wso2.iot.devices.waterlevel:1.0.0') @Export('org.wso2.iot.devices.waterlevel:1.0.0')
define stream waterlevel (meta_owner string, meta_deviceType string, meta_deviceId string, meta_time long, waterlevel float); define stream waterlevel (meta_owner string, meta_deviceType string, meta_deviceId string, meta_time long, waterlevel float);

@ -16,7 +16,7 @@
"payloadData": [ "payloadData": [
{ {
"name": "relay", "name": "relay",
"type": "BOOLEAN" "type": "BOOL"
}, },
{ {
"name": "waterlevel", "name": "waterlevel",

@ -19,22 +19,21 @@
package org.homeautomation.watertank.api; package org.homeautomation.watertank.api;
import org.homeautomation.watertank.api.dto.DeviceJSON; import org.homeautomation.watertank.api.dto.DeviceJSON;
import org.wso2.carbon.apimgt.annotations.api.API; import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission; import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType; import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature; import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Path;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.Produces; import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.PUT;
import javax.ws.rs.DELETE;
import javax.ws.rs.core.Context; import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
@ -58,34 +57,37 @@ interface DeviceTypeService {
Response registerDevice(final DeviceJSON agentInfo); Response registerDevice(final DeviceJSON agentInfo);
/** /**
* @param deviceId unique identifier for given device type * @param deviceId unique identifier for given device type
* @param onLevel level to turn on the relay * @param onLevel level to turn on the relay
* @param offLevel level to turn off thr relay * @param offLevel level to turn off the relay
* @param sensorHeight height to water level sensor from bottom of the tank
*/ */
@Path("device/{deviceId}/change-levels") @Path("device/{deviceId}/change-levels")
@POST @POST
@Feature(code = "change-levels", name = "Change on/off water levels", @Feature(code = "change-levels", name = "Update configurations",
description = "Change on/off water levels") description = "Change on/off water levels and set sensor height from the bottom of the tank")
@Permission(scope = "watertank_user", permissions = {"/permission/admin/device-mgt/change-levels"}) @Permission(scope = "watertank_user", permissions = {"/permission/admin/device-mgt/change-levels"})
Response changeOnOffLevels(@PathParam("deviceId") String deviceId, Response updateConfigs(@PathParam("deviceId") String deviceId,
@QueryParam("on") int onLevel, @QueryParam("on") int onLevel,
@QueryParam("off") int offLevel, @QueryParam("off") int offLevel,
@Context HttpServletResponse response); @QueryParam("height") int sensorHeight,
@Context HttpServletResponse response);
/** /**
* Retrieve Sensor data for the given time period * Retrieve Sensor data for the given time period
* @param deviceId unique identifier for given device type instance *
* @param deviceId unique identifier for given device type instance
* @param sensorName name of the sensor * @param sensorName name of the sensor
* @param from starting time * @param from starting time
* @param to ending time * @param to ending time
* @return response with List<SensorRecord> object which includes sensor data which is requested * @return response with List<SensorRecord> object which includes sensor data which is requested
*/ */
@Path("device/stats/{deviceId}/sensors/{sensorName}") @Path("device/stats/{deviceId}/sensors/{sensorName}")
@GET @GET
@Consumes("application/json") @Consumes("application/json")
@Produces("application/json") @Produces("application/json")
Response getSensorStats(@PathParam("deviceId") String deviceId, @PathParam("sensorName") String sensorName, Response getSensorStats(@PathParam("deviceId") String deviceId, @PathParam("sensorName") String sensorName,
@QueryParam("from") long from, @QueryParam("to") long to); @QueryParam("from") long from, @QueryParam("to") long to);
@Path("/device/{device_id}") @Path("/device/{device_id}")
@DELETE @DELETE

@ -26,7 +26,6 @@ import org.homeautomation.watertank.api.dto.SensorRecord;
import org.homeautomation.watertank.api.util.APIUtil; import org.homeautomation.watertank.api.util.APIUtil;
import org.homeautomation.watertank.api.util.ZipUtil; import org.homeautomation.watertank.api.util.ZipUtil;
import org.homeautomation.watertank.plugin.constants.DeviceTypeConstants; import org.homeautomation.watertank.plugin.constants.DeviceTypeConstants;
import org.json.JSONObject;
import org.wso2.carbon.analytics.dataservice.commons.SORT; import org.wso2.carbon.analytics.dataservice.commons.SORT;
import org.wso2.carbon.analytics.dataservice.commons.SortByField; import org.wso2.carbon.analytics.dataservice.commons.SortByField;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException; import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
@ -109,35 +108,33 @@ public class DeviceTypeServiceImpl implements DeviceTypeService {
} }
/** /**
/** * @param deviceId unique identifier for given device type
* @param deviceId unique identifier for given device type * @param onLevel level to turn on the relay
* @param onLevel level to turn on the relay * @param offLevel level to turn off the relay
* @param offLevel level to turn off thr relay * @param sensorHeight height to water level sensor from bottom of the tank
*/ */
@Path("device/{deviceId}/change-levels") @Path("device/{deviceId}/change-levels")
@POST @POST
@Feature(code = "change-levels", name = "Change on/off water levels", @Feature(code = "change-levels", name = "Update configurations",
description = "Change on/off water levels") description = "Change on/off water levels and set sensor height from the bottom of the tank")
public Response changeOnOffLevels(@PathParam("deviceId") String deviceId, public Response updateConfigs(@PathParam("deviceId") String deviceId,
@QueryParam("on") int onLevel, @QueryParam("on") int onLevel,
@QueryParam("off") int offLevel, @QueryParam("off") int offLevel,
@Context HttpServletResponse response) { @QueryParam("height") int sensorHeight,
@Context HttpServletResponse response) {
try { try {
if (!APIUtil.getDeviceAccessAuthorizationService() if (!APIUtil.getDeviceAccessAuthorizationService()
.isUserAuthorized(new DeviceIdentifier(deviceId, DeviceTypeConstants.DEVICE_TYPE))) { .isUserAuthorized(new DeviceIdentifier(deviceId, DeviceTypeConstants.DEVICE_TYPE))) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
} }
JSONObject jsonObject = new JSONObject(); String configs = onLevel + "," + offLevel + "," + sensorHeight;
jsonObject.put("on", onLevel);
jsonObject.put("off", offLevel);
Map<String, String> dynamicProperties = new HashMap<>(); Map<String, String> dynamicProperties = new HashMap<>();
String publishTopic = APIUtil.getAuthenticatedUserTenantDomain() String publishTopic = APIUtil.getAuthenticatedUserTenantDomain()
+ "/" + DeviceTypeConstants.DEVICE_TYPE + "/" + deviceId + "/command"; + "/" + DeviceTypeConstants.DEVICE_TYPE + "/" + deviceId + "/command";
dynamicProperties.put(DeviceTypeConstants.ADAPTER_TOPIC_PROPERTY, publishTopic); dynamicProperties.put(DeviceTypeConstants.ADAPTER_TOPIC_PROPERTY, publishTopic);
APIUtil.getOutputEventAdapterService().publish(DeviceTypeConstants.MQTT_ADAPTER_NAME, APIUtil.getOutputEventAdapterService().publish(DeviceTypeConstants.MQTT_ADAPTER_NAME,
dynamicProperties, jsonObject.toString()); dynamicProperties, configs);
return Response.ok().build(); return Response.ok().build();
} catch (DeviceAccessAuthorizationException e) { } catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e); log.error(e.getErrorMessage(), e);

@ -1,4 +1,4 @@
tmr.alarm(0, 1000, 0, function() tmr.alarm(0, 1000, 0, function()
dofile("wifi-connect.lua"); dofile("wifi-connect.lua");
dofile("read-sensor.lua"); dofile("water-tank.lua");
end) end)

@ -1,24 +1,76 @@
DHT = require("dht_lib") trig = 5 --IO14
echo = 7 --IO13
dht_data = 2 relay = 0 --IO16
buzzer = 1 is_relay_on = false
gpio.mode(buzzer, gpio.OUTPUT) pulse_time = 0
water_level = 0
relay_on = 10
relay_off = 100
tank_height = 120
client_connected = false client_connected = false
m = mqtt.Client("ESP8266-" .. node.chipid(), 120, "${DEVICE_TOKEN}", "") m = mqtt.Client("ESP8266-" .. node.chipid(), 120, "${DEVICE_TOKEN}", "")
tmr.alarm(0, 10000, 1, function() function save_config()
DHT.read(dht_data) file.open("config", "w+")
file.writeline(relay_on .. "," .. relay_off .. "," .. tank_height)
file.close()
print("Configs saved")
end
function read_config()
if (file.open("config") ~= nil) then
local result = string.sub(file.readline(), 1, -2) -- to remove newline character
file.close()
local v1, v2, v3 = result:match("([^,]+),([^,]+)")
relay_on = tonumber(v1)
relay_off = tonumber(v2)
tank_height = tonumber(v3)
print("Loaded configs:" .. relay_on .. "," .. relay_off .. "," .. tank_height)
else
print("Using default configs")
end
end
gpio.mode(relay, gpio.OUTPUT)
gpio.mode(trig, gpio.OUTPUT)
gpio.mode(echo, gpio.INT)
read_config()
gpio.trig(echo, "both", function(level)
local du = tmr.now() - pulse_time
if (level == 1) then
pulse_time = tmr.now()
else
-- 1cm ==> 40
water_level = tank_height - (du / 40);
if (water_level < relay_on) then
gpio.write(relay, gpio.HIGH)
is_relay_on = true
elseif (water_level > relay_off) then
gpio.write(relay, gpio.LOW)
is_relay_on = false
end
print("Water Level: " .. water_level .. " cm")
collectgarbage()
end
end)
local t = DHT.getTemperature() tmr.alarm(0, 5000, 1, function()
local h = DHT.getHumidity() gpio.write(trig, gpio.HIGH)
tmr.delay(10)
gpio.write(trig, gpio.LOW)
end)
tmr.alarm(0, 10000, 1, function()
if t == nil then if t == nil then
print("Error reading from DHTxx") print("Error reading from DHTxx")
else else
if (client_connected) then if (client_connected) then
local payload = "{event:{metaData:{owner:\"${DEVICE_OWNER}\",deviceId:\"${DEVICE_ID}\"},payloadData:{temperature:" .. t .. ", humidity:" .. h .. "}}}" local payload = "{event:{metaData:{owner:\"${DEVICE_OWNER}\",deviceId:\"${DEVICE_ID}\"},payloadData:{relay:" .. is_relay_on .. ", waterlevel:" .. water_level .. "}}}"
m:publish("carbon.super/watertank/${DEVICE_ID}/data", payload, 0, 0, function(client) m:publish("carbon.super/watertank/${DEVICE_ID}/data", payload, 0, 0, function(client)
print("Published> Temperature: " .. t .. "C Humidity: " .. h .. "%") print("Published> Water Level: " .. water_level .. "cm Relay: " .. is_relay_on .. "%")
end) end)
else else
connectMQTTClient() connectMQTTClient()
@ -39,7 +91,6 @@ function connectMQTTClient()
subscribeToMQTTQueue() subscribeToMQTTQueue()
end) end)
end end
end end
function subscribeToMQTTQueue() function subscribeToMQTTQueue()
@ -49,28 +100,15 @@ end)
m: on("message", function(client, topic, message) m: on("message", function(client, topic, message)
print("MQTT message received") print("MQTT message received")
print(message) print(message)
buzz(message == "on") local v1, v2, v3 = message: match("([^,]+),([^,]+)")
relay_on = tonumber(v1)
relay_off = tonumber(v2)
tank_height = tonumber(v3)
print("Received configs:".. relay_on.. ",".. relay_off.. ",".. tank_height)
save_config();
end) end)
m: on("offline", function(client) m: on("offline", function(client)
print("Disconnected") print("Disconnected")
client_connected = false client_connected = false
end) end)
end end
function buzz(status)
local buzzerOn = true
if(status) then
tmr. alarm(1, 500, 1, function()
if buzzerOn then
buzzerOn = false
gpio. write(buzzer, gpio. HIGH)
else
buzzerOn = true
gpio. write(buzzer, gpio. LOW)
end
end)
else
tmr. stop(1)
gpio. write(buzzer, gpio. LOW)
end
end
Loading…
Cancel
Save