import boto3
import json
import os
import pandas as pd
import statistics
import math
import datetime
import pytz
from pytz import timezone
from six.moves.urllib import request
from IPython.display import display, HTML
from matplotlib import pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
def avg_time(times):
avg = 0
for elem in times:
avg += elem.second + 60*elem.minute + 3600*elem.hour
avg /= len(times)
res = str(int(avg/3600)) + ' ' + str(int((avg%3600)/60)) + ' ' + str(int(avg%60))
return datetime.datetime.strptime(res, "%H %M %S").time()
iota = boto3.client('iotanalytics')
dataset = "illumination"
dataset_url = iota.get_dataset_content(datasetName = dataset,versionId = "$LATEST")['entries'][0]['dataURI']
df_light = pd.read_csv(dataset_url,low_memory=False)
# Convert the time which is reported UTC to local pacific time and add the index to the dataframe
df_light['datetime']=pd.DatetimeIndex(pd.to_datetime(df_light["received"]/1000, unit='s')) \
.tz_localize('UTC') \
.tz_convert('US/Pacific')
df_light.index = df_light['datetime']
response = iota.describe_dataset(datasetName = dataset)
sql = response["dataset"]["actions"][0]["queryAction"]["sqlQuery"]
g_min = df_light.resample('D')['illumination'].min()[1:-1]
g_max = df_light.resample('D')['illumination'].max()[1:-1]
start = g_min.index.min()
end = g_min.index.max()
range =g_max.mean() - g_min.mean()
percent=25/100
morning = math.ceil(g_min.mean()+range*percent)
evening = math.ceil(g_max.mean()-range*percent)
morning,evening,start,end
display(HTML('<h1 style="font-size:32px">'+sql+"</h1>"))
df_light = df_light[((df_light.datetime >= start) & (df_light.datetime <= end))]
df_light.plot(title='Light Levels',kind='area',x='datetime',y='illumination',figsize=(20,8),color='orange',linewidth=2,grid=True)
mornings=[]
df_light.sort_values(by='datetime', ascending=True, inplace=True)
for day in g_min.index:
thisDay = day.date()
for index, row in df_light.iterrows():
if (thisDay == row['datetime'].date()):
if (row['illumination'] > morning):
if (index.hour < 12) :
mornings.append(index)
print (index,row['illumination'])
break
water_on = avg_time(mornings)
display(HTML('<h1 style="font-size:48px;margin-top:4px">Water ON hour ('+str("%.0f" % water_on.hour)+'), minute ('+str("%.0f" % water_on.minute)+')</h1>'))
dataset = "temperature"
dataset_url = iota.get_dataset_content(datasetName = dataset,versionId = "$LATEST")['entries'][0]['dataURI']
df_temp = pd.read_csv(dataset_url)
# Convert the time which is reported UTC to local pacific time and add the index to the dataframe
df_temp['datetime']=pd.DatetimeIndex(pd.to_datetime(df_temp["received"]/1000, unit='s')) \
.tz_localize('UTC') \
.tz_convert('US/Pacific')
df_temp.index = df_temp['datetime']
response = iota.describe_dataset(datasetName = dataset)
sql = response["dataset"]["actions"][0]["queryAction"]["sqlQuery"]
display(HTML('<h1 style="font-size:32px">'+sql+"</h1>"))
df_temp = df_temp[\
((df_temp.datetime >= (datetime.datetime.now() - datetime.timedelta(days=3))) \
& (df_temp['full_topic'].str.contains('barometer'))) \
]
df_temp.plot(title='Temperature',kind='line',x='datetime',y='temperature',figsize=(20,8),color='red',linewidth=8,grid=True)
conditions = df_temp["temperature"].quantile([0.1,0.5,0.9])
duration = math.ceil(5*max(0,conditions[0.1]-10) + 4*max(0,conditions[0.5]-25) + 5*max(0,conditions[0.9]-29))
winter = datetime.datetime.now().month in [11,12,1,2]
if (winter) :
duration =0
display(HTML('<h1 style="font-size:48px">Water duration = '+str("%.0f" % duration)+' minutes</h1>'))
water_off = datetime.datetime.combine(datetime.datetime.now(), water_on) + datetime.timedelta(minutes=duration)
water_on = datetime.datetime.combine(datetime.datetime.now(), water_on)
print('water on (local)=',water_on)
print('water off (local)=',water_off)
water_on_local = water_on
water_off_local = water_off
tz = pytz.timezone('US/Pacific')
water_on = tz.localize(water_on.replace(tzinfo=None)).astimezone(timezone('UTC'))
water_off = tz.localize(water_off.replace(tzinfo=None)).astimezone(timezone('UTC'))
print('water on (utc)=',water_on)
print('water off (utc)=',water_off)
lambdaClient = boto3.client('lambda')
response = lambdaClient.invoke(FunctionName='IsItGoingToRain')
result = json.loads(response['Payload'].read().decode("utf-8"))
willItRain = result
ruleStatus = 'DISABLED' if (willItRain) else 'ENABLED'
cwe = boto3.client('events')
response = cwe.put_rule(
Name='water-on',\
ScheduleExpression='cron('+str(water_on.minute)+' '+str(water_on.hour)+' ? * * *)',\
State=ruleStatus,\
Description='Autogenerated rule to turn the water ON at the specified time')
response = cwe.put_rule(
Name='water-off',\
ScheduleExpression='cron('+str(water_off.minute)+' '+str(water_off.hour)+' ? * * *)',\
State=ruleStatus,\
Description='Autogenerated rule to turn the water OFF at the specified time')
output = {"generated":datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),\
"duration":duration,\
"on":water_on.strftime("%H:%M:%S"),\
"off":water_off.strftime("%H:%M:%S"),\
"winter":winter,\
"rain_forecast":willItRain,\
"p10":round(conditions[0.1],1),\
"p50":round(conditions[0.5],1),\
"p90":round(conditions[0.9],1)\
}
json.dumps(output)
iot = boto3.client('iot-data', region_name='us-west-2')
response = iot.publish(topic='rtjm/irrigation',qos=1,payload=json.dumps(output))
message = 'Next water on at '+water_on_local.strftime("%H:%M:%S")+' for '+str(duration)+' minutes. Rain forecast is '+str(willItRain)+'. Recent highs of '+str(round(conditions[0.9],1))+' celcius'
sns = boto3.client('sns')
response = sns.publish(TopicArn='arn:aws:sns:us-west-2:165642864119:information-service',Message=message)
dataset = "telescope_daily"
dataset_url = iota.get_dataset_content(datasetName = dataset,versionId = "$LATEST")['entries'][0]['dataURI']
df = pd.read_csv(dataset_url,low_memory=False)
df['datetime'] = pd.to_datetime(df["received"]/1000, unit='s')
df.index = df['datetime']
analysis = df[((df['flow'] >= 0))]
response = iota.describe_dataset(datasetName = dataset)
sql = response["dataset"]["actions"][0]["queryAction"]["sqlQuery"]
display(HTML('<h1 style="font-size:32px">'+sql+"</h1>"))
analysis.plot(title='Irrigation Flow Rates',kind='area',x='datetime',y='flow',figsize=(20,8),color='blue',linewidth=2,grid=True)