<file_sep># -*- coding: utf-8 -*-
import json
import csv
import re
import sys
import time
import datetime
from datetime import timedelta

import io   # for utf-8 encoding
import subprocess
from sys     import stderr


# Python program to print from https://www.geeksforgeeks.org/print-colors-python-terminal/ 
# colored text and background 
def prRed(skk): 		print(u"\033[91m {}\033[00m" .format(skk)), 
def prGreen(skk): 		print(u"\033[92m {}\033[00m" .format(skk)), 
def prYellow(skk): 		print(u"\033[93m {}\033[00m" .format(skk)), 
def prLightPurple(skk): print(u"\033[94m {}\033[00m" .format(skk)), 
def prPurple(skk): 		print(u"\033[95m {}\033[00m" .format(skk)), 
def prCyan(skk): 		print(u"\033[96m {}\033[00m" .format(skk)), 
def prLightGray(skk): 	print(u"\033[97m {}\033[00m" .format(skk)), 
def prBlack(skk): 		print(u"\033[98m {}\033[00m" .format(skk)), 

def prInverse(skk): 	print(u"\033[7m {}\033[00m" .format(skk)), 
def prBold(skk): 		print(u"\033[1m {}\033[00m" .format(skk)), 



def prUnderline(skk): 				print(u"\033[04m {}\033[00m" .format(skk)), 
def prStrikethrough(skk): 			print(u"\033[09m {}\033[00Access_token_secretm" .format(skk)), 
def prBoldStrikethrough(skk): 		print(u"\033[1m\033[09m {}\033[00m" .format(skk)), 
def prBoldUnderline(skk): 			print(u"\033[1m\033[04m {}\033[00m" .format(skk)), 
def prInverseStrikethrough(skk):	print(u"\033[7m\033[09m {}\033[00m" .format(skk)), 
def prInverseUnderline(skk): 		print(u"\033[7m\033[04m {}\033[00m" .format(skk)), 

		
# MAIN SECTION

try:
	with open('stats.json') as json_data2:
		data = json.load(json_data2)
		if bool(data) == False: # empty dictionary
			prYellow('tweet.py: stats.json is empty')
			sys.exit()
		else:
			print ("lookin g in")
			print (str(data))
			last_reading_datetime = data['last_reading_datetime']
  
except IOError:
	prYellow('stats.py: cannot read twitter_keys.json')
	sys.exit()

last_reading_datetime_dt = datetime.datetime.fromisoformat(last_reading_datetime)
a15_minutes_ago = datetime.datetime.now() - timedelta(minutes=29)
print ('time now=' + str(datetime.datetime.now()))
print ('last_reading_datetime=' + str(last_reading_datetime))
print ('15 minutes ago=       ' + str(a15_minutes_ago))

if last_reading_datetime_dt < a15_minutes_ago:
	shell_string = '"C:\Program Files\VideoLAN\VLC\vlc.exe" --loop morse_CO2.mp3'
	shell_string = './alarm.sh'

	subprocess.call([shell_string], shell = True)	
<file_sep># -*- coding: utf-8 -*-
import json
import csv
import re
import sys
import time
import datetime
from datetime import timedelta
import twitter

import io   # for utf-8 encoding
#import subprocess
from sys     import stderr


# Python program to print from https://www.geeksforgeeks.org/print-colors-python-terminal/ 
# colored text and background 
def prRed(skk): 		print(u"\033[91m {}\033[00m" .format(skk)), 
def prGreen(skk): 		print(u"\033[92m {}\033[00m" .format(skk)), 
def prYellow(skk): 		print(u"\033[93m {}\033[00m" .format(skk)), 
def prLightPurple(skk): print(u"\033[94m {}\033[00m" .format(skk)), 
def prPurple(skk): 		print(u"\033[95m {}\033[00m" .format(skk)), 
def prCyan(skk): 		print(u"\033[96m {}\033[00m" .format(skk)), 
def prLightGray(skk): 	print(u"\033[97m {}\033[00m" .format(skk)), 
def prBlack(skk): 		print(u"\033[98m {}\033[00m" .format(skk)), 

def prInverse(skk): 	print(u"\033[7m {}\033[00m" .format(skk)), 
def prBold(skk): 		print(u"\033[1m {}\033[00m" .format(skk)), 



def prUnderline(skk): 				print(u"\033[04m {}\033[00m" .format(skk)), 
def prStrikethrough(skk): 			print(u"\033[09m {}\033[00Access_token_secretm" .format(skk)), 
def prBoldStrikethrough(skk): 		print(u"\033[1m\033[09m {}\033[00m" .format(skk)), 
def prBoldUnderline(skk): 			print(u"\033[1m\033[04m {}\033[00m" .format(skk)), 
def prInverseStrikethrough(skk):	print(u"\033[7m\033[09m {}\033[00m" .format(skk)), 
def prInverseUnderline(skk): 		print(u"\033[7m\033[04m {}\033[00m" .format(skk)), 

		
# MAIN SECTION

try:
	with open('stats.json') as json_data2:
		data = json.load(json_data2)
		if bool(data) == False: # empty dictionary
			prYellow('tweet.py: stats.json is empty')
			sys.exit()
		else:
			print ("lookin g in")
			line1 			= data['line1']
			line2 			= data['line2']
			line3 			= data['line3']
			site_location	= data['site_location']
			last_reading	= data['last_reading']
			lowest_reading	= data['lowest_reading']
			highest_reading	= data['highest_reading']
  
except IOError:
	prYellow('stats.py: cannot read twitter_keys.json')
	sys.exit()

print (line1)
print (line2)
print (line3)

try:
	with open('apikeys/twitter_keys.json') as json_data2:
		data = json.load(json_data2)
		if bool(data) == False: # empty dictionary
			prYellow('tweet.py: twitter_keys.json is empty')
			sys.exit()
		else:
			consumer_key 		= data['consumer_key']
			consumer_secret 	= data['consumer_secret']
			access_token_key 	= data['access_token_key']
			access_token_secret	= data['access_token_secret']
except IOError:
	prYellow('tweet.py: cannot read twitter_keys.json')
	sys.exit()

print (consumer_key)
print (consumer_secret)
print (access_token_key)
print (access_token_secret)

api = twitter.Api(consumer_key=consumer_key,
					consumer_secret = consumer_secret,
					access_token_key = access_token_key,
					access_token_secret = access_token_secret)
					
print (api.VerifyCredentials())
#message = "Hello World! Lets try some ways to get a subscript '2': unicode:" + u"\u2082" + " and the html entity: 	&#8322;" 
#post_update = api.PostUpdates(status=message)

line1_clean = line1.replace('&nbsp;','').replace('reading:','reading: ')

if last_reading	== lowest_reading:
	message = "Record low outdoor CO" + u"\u2082" + " at " + str(site_location) + line1_clean[12:] + ". This is the highest value recorded since 15th November 2018. Graphs and info at https://conwasa.github.io/CO2_play/ #CO2"
	print (message)

elif last_reading	== highest_reading:
	message = "Record high outdoor CO" + u"\u2082" + " at " + str(site_location) + line1_clean[12:] + ". This is the highest value recorded since 15th November 2018. Graphs and info at https://conwasa.github.io/CO2_play/ #CO2"
else:
	message = "Outdoor CO" + u"\u2082" + " at " + str(site_location) + ", " + line1_clean + ". Graphs and info at https://conwasa.github.io/CO2_play/ \n#CO2"

#message = "Record low outdoor CO" + u"\u2082" + " at " + str(site_location) + ': 389ppm at 01:59 on Sunday 27 Jan 2019' + ". This is the lowest value recorded since 15th November 2018. Graphs and info at https://conwasa.github.io/CO2_play/ #CO2"

try:
	print ('null')
	post_update = api.PostUpdates(status=message)
except Exception as e:
	prYellow('tweet.py: twitter error')
	prYellow('twitter.error.TwitterError')
	prYellow('hello')
	prYellow(e)
	
	sys.exit()
	# [{'code': 326, 'message': 'To protect our users from spam and other malicious activity, this account is temporarily locked. 
	#Please log in to https://twitter.com to unlock your account.'}		
print (message)

<file_sep>wine /home/user2/SenselifeCamSoftware/CO2_Monitor.exe &
while [ true ]; do
	rm alarm_flag_for_telegram_bot.flag
	cat /home/user2/SenselifeCamSoftware/2018/11/*.CSV |grep "20" > all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2018/12/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/01/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/02/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/03/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/04/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/05/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/06/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/07/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/08/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/09/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/10/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/11/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2019/12/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/01/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/02/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/03/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/04/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/05/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/06/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/07/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/08/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/09/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/10/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/11/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2020/12/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/01/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/02/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/03/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/04/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/05/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/06/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/07/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/08/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/09/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/10/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/11/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2021/12/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/01/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/02/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/03/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/04/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/05/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/06/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/07/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/08/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/09/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/10/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/11/*.CSV |grep "20" >> all_readings.csv 
	cat /home/user2/SenselifeCamSoftware/2022/12/*.CSV |grep "20" >> all_readings.csv 
	# copy stats.json prev_stats.json
	python3 process_csv.py	#python3 because uses list2 = list.copy()
	python tweet.py
	gsutil -h "Cache-Control:public, max-age=0" -m cp outages.csv gs://uk_bn3_co2 | echo $?  
	gsutil -h "Cache-Control:public, max-age=0" -m cp todays_readings.csv gs://uk_bn3_co2 | echo $? 
	gsutil -h "Cache-Control:public, max-age=0" -m cp stats.json gs://uk_bn3_co2 | echo $?
	if [ ! -f "done_daily_copy_flag.txt" ]; then
		if [ $(date +%H) -eq '00' ]; then
		  gsutil -h "Cache-Control:public, max-age=0" cp all_historic_readings.csv gs://uk_bn3_co2 | echo $?
		  gsutil -h "Cache-Control:public, max-age=0" cp all_readings.csv gs://uk_bn3_co2 | echo $?
		  gsutil -h "Cache-Control:public, max-age=0" cp day_befores_readings.csv gs://uk_bn3_co2 | echo $?
		  gsutil -h "Cache-Control:public, max-age=0" cp last_months_readings.csv gs://uk_bn3_co2 | echo $?
		  gsutil -h "Cache-Control:public, max-age=0" cp last_weeks_readings.csv gs://uk_bn3_co2 | echo $?
		  gsutil -h "Cache-Control:public, max-age=0" cp week_before_lasts_readings.csv gs://uk_bn3_co2 | echo $?
		  gsutil -h "Cache-Control:public, max-age=0" cp yesterdays_readings.csv gs://uk_bn3_co2 | echo $?
		  copy flag.txt done_daily_copy_flag.txt
		fi
	fi
	if [ $(date +%H) -eq '01' ]; then
		rm done_daily_copy_flag.txt
		echo "flag file deleted"
	fi
	python3 monitor_sensor_connection.py
	echo $(date +%H:%M:%S)
	# Script take 70s to run on Windows laptop, test again todo
	echo "start timeout"
	sleep 530
done
<file_sep>(function() {
  var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['latest_co2_readings'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = ((helper = (helper = lookupProperty(helpers,"line1") || (depth0 != null ? lookupProperty(depth0,"line1") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"line1","hash":{},"data":data,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":11}}}) : helper))) != null ? stack1 : "")
    + "<br>"
    + ((stack1 = ((helper = (helper = lookupProperty(helpers,"line2") || (depth0 != null ? lookupProperty(depth0,"line2") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"line2","hash":{},"data":data,"loc":{"start":{"line":1,"column":15},"end":{"line":1,"column":26}}}) : helper))) != null ? stack1 : "")
    + "<br>"
    + ((stack1 = ((helper = (helper = lookupProperty(helpers,"line3") || (depth0 != null ? lookupProperty(depth0,"line3") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"line3","hash":{},"data":data,"loc":{"start":{"line":1,"column":30},"end":{"line":1,"column":41}}}) : helper))) != null ? stack1 : "")
    + "<br>";
},"useData":true});
})();<file_sep># -*- coding: utf-8 -*-
import os
import json
import csv
import re
import sys
import time
import datetime
from datetime import timedelta
import io   # for utf-8 encoding
from sys     import stderr
# python-telegram-bot.org specific imports
import logging
from telegram import Update
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackContext
#enable logging
logging.basicConfig(
	format='%asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
)

logger = logging.getLogger(__name__)

def get_latest_stats():

	try:
		with open('stats.json') as json_data2:
			data = json.load(json_data2)
			if bool(data) == False: # empty dictionary
				prYellow('telegram_bot.py: stats.json is empty')
				sys.exit()
			else:
				line1 			= data['line1']
				line2 			= data['line2']
				line3 			= data['line3']
				site_location	= data['site_location']
				last_reading	= data['last_reading']
				lowest_reading	= data['lowest_reading']
				highest_reading	= data['highest_reading']
				weekly_trend	= data['weekly_trend']
				monthly_trend	= data['monthly_trend']
				annual_trend	= data['annual_trend']

	except IOError:
		print ('stats.py: cannot read stats.json')
		sys.exit()

	line1_clean = line1.replace('&nbsp;','').replace('reading:','reading: ')

	if last_reading	== lowest_reading:
		message = "Record low outdoor CO" + u"\u2082" + " at " + str(site_location) + line1_clean[12:] + ". This is the lowest value recorded since 15th November 2018. Graphs and info at https://conwasa.github.io/CO2_play/ #CO2"
		print (message)

	elif last_reading	== highest_reading:
		message = "Record high outdoor CO" + u"\u2082" + " at " + str(site_location) + line1_clean[12:] + ". This is the highest value recorded since 15th November 2018. Graphs and info at https://conwasa.github.io/CO2_play/ #CO2"
	else:
		message = "Outdoor CO" + u"\u2082" + " at " + str(site_location) + ", " + line1_clean + ". Graphs and info at https://conwasa.github.io/CO2_play/ \n#CO2"

	if int(last_reading) > 1000:
		co2_gt_1000_value = int(last_reading)
	else:
		co2_gt_1000_value = 0
		
	return ([message, site_location, co2_gt_1000_value, weekly_trend, monthly_trend, annual_trend])
	
def get_spoken_time_since_last_char(time_since_last_chat):
	mins_since_last_chat = int(time.strftime("%M", time.localtime(time_since_last_chat)))
	hours_since_last_chat = int(time.strftime("%H", time.localtime(time_since_last_chat)))
	days_since_last_chat = int(time.strftime("%j", time.localtime(time_since_last_chat))) - 1
	years_since_last_chat = int(time.strftime("%Y", time.localtime(time_since_last_chat))) - 1970
	if years_since_last_chat != 0:
		days_since_last_chat = days_since_last_chat + years_since_last_chat * 365
	if days_since_last_chat == 1:
		hours_since_last_chat = hours_since_last_chat + 24
		days_since_last_chat = 0
	if hours_since_last_chat == 1:
		mins_since_last_chat = mins_since_last_chat + 60
		hours_since_last_chat = 0
	spoken_time_since_last_chat = str(mins_since_last_chat) + " minutes"
	if hours_since_last_chat != 0:
		spoken_time_since_last_chat = str(hours_since_last_chat) + " hours and " + spoken_time_since_last_chat 
	if days_since_last_chat != 0:
		spoken_time_since_last_chat = str(days_since_last_chat) + " days, " + spoken_time_since_last_chat 
	return (spoken_time_since_last_chat)
	

def load_subscriptions_dict():
# I didn't know about the pickle library at the time of writing. 
# search 'python pickle dictionary' for more information.
	subscriptions_dict = {}
	 
	try:
		with open('subscriptions.json') as json_data:
			subscriptions_dict = json.load(json_data)
			if bool(subscriptions_dict) == False: # empty dictionary
				prYellow('telegram_bot.py: subscription dictionary empty')
				sys.exit()
	except (ValueError, IOError):
		# first run, create empty topic lists
		subscriptions_dict = {  'new records' : [],
								'all readings' : [], 
								'service msgs' : [], 
								'dev news' : [],
								'weekly trend' : [],
								'monthly trend' : [],
								'annual trend' : []
		}
		with open('subscriptions.json', 'w') as write_file:
			json.dump(subscriptions_dict, write_file, indent=2) 
		
	return subscriptions_dict

def add_subscription(subscriptions_dict, chat_id, topic, context):
	chat_id_list = subscriptions_dict[topic]
	if chat_id not in chat_id_list: 
		chat_id_list.append(chat_id)
		subscriptions_dict[topic] = chat_id_list
		with open('subscriptions.json', 'w') as write_file:
			json.dump(subscriptions_dict, write_file, indent=2) 
		context.bot.send_message(chat_id=chat_id, text="you are subscribed to " + topic)
	else:
		context.bot.send_message(chat_id=chat_id, text="you are already subscribed to " + topic)
	return subscriptions_dict

def remove_subscription(subscriptions_dict, chat_id, topic, context):
	chat_id_list = subscriptions_dict[topic]
	if chat_id in chat_id_list: 
		chat_id_list.remove(chat_id)
		subscriptions_dict[topic] = chat_id_list
		with open('subscriptions.json', 'w') as write_file:
			json.dump(subscriptions_dict, write_file, indent=2) 
		context.bot.send_message(chat_id=chat_id, text="you are unsubscribed from " + topic)
	else:
		context.bot.send_message(chat_id=chat_id, text="you are already unsubscribed from " + topic)
	return subscriptions_dict

def	notify_subscribers(subscriptions_dict, topic, message):
	chat_id_list = subscriptions_dict[topic]
	for chat_id in chat_id_list:
		updater.bot.send_message(chat_id=chat_id, text=message)

def send_start_and_reply_msg(update, context):
	print ("telegram chatbot event chat_id=" + str(update.effective_chat.id) + " received message=" + update.message.text)
	epoch_time_now = int(time.time())
	time_since_last_chat = epoch_time_now - last_spoken_to_epoch_time
	if time_since_last_chat > 6000:  # 6000 seconds is 10 minutes
		spoken_time_since_last_chat = get_spoken_time_since_last_char(time_since_last_chat)
		context.bot.send_message(chat_id=update.effective_chat.id, text="Thank you, no-one has spoken to me for " + spoken_time_since_last_chat + ".")
		
	stats_list = get_latest_stats()
	co2_message = stats_list[0]
	context.bot.send_message(chat_id=update.effective_chat.id, text=co2_message)
	context.bot.send_message(chat_id=update.effective_chat.id, text="I measure local outdoor CO" + u"\u2082" + " levels and send messages about readings and trends.\n\nType or tap '/help' for commands.")

def format_service_message(update, context, activity_name):
	chat_id = str(update.message.chat_id)
	first_name = update.message.chat.first_name
	last_name = update.message.chat.last_name
	username = update.message.chat.username
	print("chat_id : {} and firstname : {} lastname : {}  username {}". format(chat_id, first_name, last_name , username))
	message = first_name + " " + activity_name  # chat_id removed as anyone can subscribe to 'service msgs' and it could be spammed
	return message

def	join_and_print(chat_id, cmd, list):
	chat_id = str(chat_id)
	parm = ' '.join(list)
	print (chat_id + " command=/" + cmd + " " + parm)
	return (parm)
	
# MAIN SECTION

subscriptions_dict = load_subscriptions_dict()

try:
	with open('apikeys/telegram_keys.json') as json_data2:
		data = json.load(json_data2)
		if bool(data) == False: # empty dictionary
			prYellow('telegram_bot.py: telegram_keys.json is empty')
			sys.exit()
		else:
			telegram_co2_bot_token	= data['telegram_co2_bot_token']
except IOError:
	prYellow('telegram_bot.py: cannot read telegram_keys.json')
	sys.exit()

last_spoken_to_epoch_time = int(time.time())

stats_list = get_latest_stats()
co2_message = stats_list[0]
site_location = stats_list[1]

from telegram.ext import Updater
updater = Updater(token=telegram_co2_bot_token, use_context=True)

dispatcher = updater.dispatcher

def start(update, context):
	send_start_and_reply_msg(update, context)
	message = format_service_message(update, context, 'has started this bot.')
	notify_subscribers(subscriptions_dict, 'service msgs', message)
	
	from telegram.ext import CommandHandler
start_handler = CommandHandler('start', start)
dispatcher.add_handler(start_handler)

def reply(update, context):
	send_start_and_reply_msg(update, context)
	message = format_service_message(update, context, 'is chatting: ' + update.message.text)
	notify_subscribers(subscriptions_dict, 'service msgs', message)
	
from telegram.ext import MessageHandler, Filters
reply_handler = MessageHandler(Filters.text & (~Filters.command), reply)
dispatcher.add_handler(reply_handler)

def help(update, context):
	message = """Commands:
	/sub <topic> - subscribe to a topic
	/unsub <topic> - unsubscribe
	/info  <topic> - details of a topic
	/show <data> - interactive console
	/help - this message
	
	Topics are:
	weekly trend - end of week summary of trend
	monthly trend - end of month summary of trend
	annual trend - end of year summary of trend
	all trends - weekly, monthly and annual trends
	
	new records - record high or low values
	all readings - a message every 10 minutes
	
	service msgs - mainly for the robot's owner
	dev news - my software and maker stuff
	
	all - all of the above
	
	Data:
	subs - list your subscriptions
	trends - list the last trend records
	last reading - shows the last reading

	example:
	/sub monthly trend\n"""
	
	context.bot.send_message(chat_id=update.effective_chat.id, text=message)
	message = format_service_message(update, context, '/help ')
	notify_subscribers(subscriptions_dict, 'service msgs', message)
#	/about - how school teachers can use this\n

help_handler = CommandHandler('help', help)
dispatcher.add_handler(help_handler)

# topic descriptions for the /info command
new_records_info = """Info: 'new records' topic. Messages look like this:\n
	Record low outdoor CO""" + u"\u2082" + """ at """ + str(site_location) + """: 381ppm at 12:57 on Wednesday 24 Apr 2019. This is the lowest value recorded since 15th November 2018. Graphs and info at https://conwasa.github.io/CO2_play/ #CO2\n
	Record high outdoor CO""" + u"\u2082" + """ at """ + str(site_location) + """: 625ppm at 09:24 on Thursday 05 Dec 2019. This is the highest value recorded since 15th November 2018. Graphs and info at https://conwasa.github.io/CO2_play/ #CO2"\n
	Expect one message or so a year."""

all_readings_info = "Info: 'all readings' topic. A message wen a new reading is taken. Messages look like this:\n\n" + co2_message + "\n\nExpect a message every 10 minutes."

service_msgs_info = """Info: 'service msgs' topic. Messages for this Bot's owner. They look like this:\n
	Alex has started this bot.
	Bob is chatting: hello
	Bob /info dev news
	The CO2 sensor is offline.
	High CO2 1500ppm. Possible fire.\n
	Expect a few messages a week."""
	
dev_news_info = """Info: 'dev news' topic.\nNews of updates to this robot and others. \n
	Expect one message every month or so."""
		
weekly_trend_info = "Info: 'weekly trend' topic. Sent at 9am (" + site_location + """) Mondays, giving the trend based the average of previous Monday's and Sunday's readings. Messages look like tis:
	
	Weekly CO2 trend: up 3.0 percent from 492 to 502 ppm 

	Expect one message a week."""

monthly_trend_info = "Info: 'monthly trend' topic. Sent at 9am (" + site_location + """) on the first of each month, giving the trend based the average reading of the first and last days of the previous month. Messages look like tis:
	
	Monthly CO2 trend: up 1.6 percent from 490 to 492 ppm 

	Expect one message a month."""

annual_trend_info = "Info: 'annual trend' topic. Sent at 9am (" + site_location + """) on the first day of year, giving the trend based the average reading of the first and last days of the previous year. Messages look like tis:
	
	Annual CO2 trend: down 2.6 percent from 492 to 486 ppm 

	Expect one message a year."""

all_trends_info = """Info: 'all trends' topic. All three trend topics. Messages look like this:
	
	Weekly CO2 trend: up 3.0 percent from 492 to 502 ppm 
	Monthly CO2 trend: up 1.6 percent from 490 to 492 ppm 
	Annual CO2 trend: down 2.6 percent from 492 to 486 ppm 

	Expect one or so message a week."""

all_info = """Info: 'all' topic. All messages from this Bot.\n
	Expect one message every 10 minutes plus a few more a day."""

show_subs_info = """Info: 'show subs' topic. Lists your subscribed topics .\n
	On demand."""
	
def info(update, context):
	parm = join_and_print(update.effective_chat.id, 'info', context.args)
#	parm = ' '.join(context.args)
	if parm == 'new records':
		message = new_records_info
	elif parm == 'all readings':
		message = all_readings_info
	elif parm == 'service msgs':
		message = service_msgs_info
	elif parm == 'dev news':
		message = dev_news_info
	elif parm == 'weekly trend':
		message = weekly_trend_info
	elif parm == 'monthly trend':
		message = monthly_trend_info
	elif parm == 'annual trend':
		message = annual_trend_info
	elif parm == 'all trends':
		message = all_trends_info
	elif parm == 'all':
		message = new_records_info + "\n\n" + all_readings_info + "\n\n" + service_msgs_info + "\n\n" + dev_news_info + "\n\n" + weekly_trend_info + "\n\n" + monthly_trend_info + "\n\n" + annual_trend_info + "\n\n" + all_trends_info + "\n\n" + all_info
	elif parm == 'show_subs':
		message = show_subs_info
	elif parm == '':
		context.bot.send_message(chat_id=update.effective_chat.id, text='you must specify one of tese topics:\n\nnew records\nall readings\nservice msgs\ndev news\nall')
	else:
		message = parm + " not found, see /help"
	context.bot.send_message(chat_id=update.effective_chat.id, text=message)
	message = format_service_message(update, context, '/info ' + parm)
	notify_subscribers(subscriptions_dict, 'service msgs', message)

info_handler = CommandHandler('info', info)
dispatcher.add_handler(info_handler)

def sub(update, context):
	parm = join_and_print(update.effective_chat.id, 'sub', context.args)
	if parm in ['new records', 'all readings', 'service msgs', 'dev news', 'weekly trend', 'monthly trend', 'annual trend' ]:
		add_subscription(subscriptions_dict, str(update.effective_chat.id), parm, context)
	elif parm == 'all trends':
		add_subscription(subscriptions_dict, str(update.effective_chat.id), 'weekly trend', context)
		add_subscription(subscriptions_dict, str(update.effective_chat.id), 'monthly trend', context)
		add_subscription(subscriptions_dict, str(update.effective_chat.id), 'annual trend', context)
	elif parm == 'all':
		add_subscription(subscriptions_dict, str(update.effective_chat.id), 'new records', context)
		add_subscription(subscriptions_dict, str(update.effective_chat.id), 'all readings', context)
		add_subscription(subscriptions_dict, str(update.effective_chat.id), 'service msgs', context)
		add_subscription(subscriptions_dict, str(update.effective_chat.id), 'dev news', context)
		add_subscription(subscriptions_dict, str(update.effective_chat.id), 'weekly trend', context)
		add_subscription(subscriptions_dict, str(update.effective_chat.id), 'monthly trend', context)
		add_subscription(subscriptions_dict, str(update.effective_chat.id), 'annual trend', context)
	elif parm == '':
		context.bot.send_message(chat_id=update.effective_chat.id, text='you must specify one of tese topics:\n\nnew records\nall readings\nservice msgs\ndev news\nall')
	else:
		message = parm + " is not a valid topic, see /help"
		context.bot.send_message(chat_id=update.effective_chat.id, text=message)
	message = format_service_message(update, context, '/sub ' + parm)
	notify_subscribers(subscriptions_dict, 'service msgs', message)

sub_handler = CommandHandler('sub', sub)
dispatcher.add_handler(sub_handler)

def unsub(update, context):
	parm = join_and_print(update.effective_chat.id, 'sub', context.args)
	if parm in ['new records', 'all readings', 'service msgs', 'dev news', 'weekly trend', 'monthly trend', 'annual trend' ]:
		remove_subscription(subscriptions_dict, str(update.effective_chat.id), parm, context)
	elif parm == 'all trends':
		remove_subscription(subscriptions_dict, str(update.effective_chat.id), 'weekly trend', context)
		remove_subscription(subscriptions_dict, str(update.effective_chat.id), 'monthly trend', context)
		remove_subscription(subscriptions_dict, str(update.effective_chat.id), 'annual trend', context)
	elif parm == 'all':
		remove_subscription(subscriptions_dict, str(update.effective_chat.id), 'new records', context)
		remove_subscription(subscriptions_dict, str(update.effective_chat.id), 'all readings', context)
		remove_subscription(subscriptions_dict, str(update.effective_chat.id), 'service msgs', context)
		remove_subscription(subscriptions_dict, str(update.effective_chat.id), 'dev news', context)
		remove_subscription(subscriptions_dict, str(update.effective_chat.id), 'weekly trend', context)
		remove_subscription(subscriptions_dict, str(update.effective_chat.id), 'monthly trend', context)
		remove_subscription(subscriptions_dict, str(update.effective_chat.id), 'annual trend', context)
	elif parm == '':
		context.bot.send_message(chat_id=update.effective_chat.id, text='you must specify one of tese topics:\n\nnew records\nall readings\nservice msgs\ndev news\nall')
	else:
		message = parm + " is not a valid topic, see /help"
		context.bot.send_message(chat_id=update.effective_chat.id, text=message)
	message = format_service_message(update, context, '/unsub ' + parm)
	notify_subscribers(subscriptions_dict, 'service msgs', message)
	
unsub_handler = CommandHandler('unsub', unsub)
dispatcher.add_handler(unsub_handler)

def show_sub(subscriptions_dict, topic, update, context):
	chat_id = update.message.chat_id
	chat_id_list = subscriptions_dict[topic]
	
	if str(chat_id) in chat_id_list:
		context.bot.send_message(chat_id=chat_id, text="you are subscribed to " + topic)
		return True
	else:
		return False
		
def show(update, context):
	parm = join_and_print(update.effective_chat.id, 'show', context.args)
	if parm == 'subs':
		has_subs = False
		for topic in ['new records', 'all readings', 'service msgs', 'dev news', 'weekly trend', 'monthly trend', 'annual trend' ]:
			subbed = show_sub(subscriptions_dict, topic, update, context)
			if subbed == True:
				has_subs = True
		if has_subs == False:
			context.bot.send_message(chat_id=update.effective_chat.id, text='you have no subscriptions')
	elif parm == 'trends':
		context.bot.send_message(chat_id=update.effective_chat.id, text=weekly_trend)
		context.bot.send_message(chat_id=update.effective_chat.id, text=monthly_trend)
		context.bot.send_message(chat_id=update.effective_chat.id, text=annual_trend)
	elif parm == 'last reading':
		context.bot.send_message(chat_id=update.effective_chat.id, text=co2_message)
	elif parm == '':
		context.bot.send_message(chat_id=update.effective_chat.id, text='you must specify one of tese topics:\n\nnew records\nall readings\nservice msgs\ndev news\nall')
	else:
		message = parm + " is not a valid data set, see /help"
		context.bot.send_message(chat_id=update.effective_chat.id, text=message)
	
show_handler = CommandHandler('show', show)
dispatcher.add_handler(show_handler)

# timer section
job_queue = updater.job_queue

def send_weekly_message(context):
	notify_subscribers(subscriptions_dict, 'weekly trend', weekly_trend)
job_queue.run_daily(send_weekly_message, datetime.time(9, 00, 00, 000000),days=[0])

def send_monthly_message(context):
	notify_subscribers(subscriptions_dict, 'monthly trend', monthly_trend)
job_queue.run_monthly(send_monthly_message, datetime.time(9, 00, 00, 000000), 1)

now = datetime.datetime.now()
next_year = now.year + 1
annual_msg_datetime = datetime.datetime(next_year, 1, 1, 9, 00)
def send_annual_message(context):
	notify_subscribers(subscriptions_dict, 'annual trend', annual_trend)
	next_year = now.year + 1
	job_queue.run_once(send_annual_message, annual_msg_datetime)
job_queue.run_once(send_annual_message, annual_msg_datetime)

#this must be last
def unknown(update, context):
	context.bot.send_message(chat_id=update.effective_chat.id, text="Sorry, I didn't understand that command.")
unknown_handler = MessageHandler(Filters.command, unknown)
dispatcher.add_handler(unknown_handler)

updater.start_polling()

old_co2_message = ''
while True:
	stats_list = get_latest_stats()
	co2_message = stats_list[0]
	co2_gt_1000_value = stats_list[2]
	weekly_trend = stats_list[3]
	monthly_trend = stats_list[4]
	annual_trend = stats_list[5]
	if co2_message != old_co2_message:
		now = datetime.datetime.now()
		print (str(now.strftime("%Y-%m-%d %H:%M:%S")) + " " + co2_message)
		old_co2_message = co2_message
		notify_subscribers(subscriptions_dict, 'all readings', co2_message)
		if 'Record' in co2_message:
			notify_subscribers(subscriptions_dict, 'new records', co2_message)
	
	try:
		f = open("alarm_flag_for_telegram_bot.flag")
		notify_subscribers(subscriptions_dict, 'service msgs', 'The CO2 sensor is offline')
		f.close()
		os.remove("alarm_flag_for_telegram_bot.flag")
	except IOError:
		pass
	
	if co2_gt_1000_value > 0:
		notify_subscribers(subscriptions_dict, 'service msgs', 'High CO2 ' + str(co2_gt_1000_value) + 'ppm. Possible fire.')

	time.sleep (10)<file_sep># -*- coding: utf-8 -*-
import json
import csv
import re
import sys
import time
import datetime
from datetime import timedelta

import io   # for utf-8 encoding
#import subprocess
import locale
from sys     import stderr

#print '<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'  
#print 'parms passed to find_pips_v3.py:'
#print '$1=', sys.argv[1] 
#print '$2=', sys.argv[2]
#print '$3=', sys.argv[3]
#print '$4=', sys.argv[4]
#print '<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'  

# Python program to print from https://www.geeksforgeeks.org/print-colors-python-terminal/ 
# colored text and background 
def prRed(skk): 		print(u"\033[91m {}\033[00m" .format(skk)), 
def prGreen(skk): 		print(u"\033[92m {}\033[00m" .format(skk)), 
def prYellow(skk): 		print(u"\033[93m {}\033[00m" .format(skk)), 
def prLightPurple(skk): print(u"\033[94m {}\033[00m" .format(skk)), 
def prPurple(skk): 		print(u"\033[95m {}\033[00m" .format(skk)), 
def prCyan(skk): 		print(u"\033[96m {}\033[00m" .format(skk)), 
def prLightGray(skk): 	print(u"\033[97m {}\033[00m" .format(skk)), 
def prBlack(skk): 		print(u"\033[98m {}\033[00m" .format(skk)), 

def prInverse(skk): 	print(u"\033[7m {}\033[00m" .format(skk)), 
def prBold(skk): 		print(u"\033[1m {}\033[00m" .format(skk)), 


#    underline='\033[04m'
#    reverse='\033[07m'
#    strikethrough='\033[09m'

def prUnderline(skk): 				print(u"\033[04m {}\033[00m" .format(skk)), 
def prStrikethrough(skk): 			print(u"\033[09m {}\033[00m" .format(skk)), 
def prBoldStrikethrough(skk): 		print(u"\033[1m\033[09m {}\033[00m" .format(skk)), 
def prBoldUnderline(skk): 			print(u"\033[1m\033[04m {}\033[00m" .format(skk)), 
def prInverseStrikethrough(skk):	print(u"\033[7m\033[09m {}\033[00m" .format(skk)), 
def prInverseUnderline(skk): 		print(u"\033[7m\033[04m {}\033[00m" .format(skk)), 

def read_csv_file():
#	with open(filename, mode="r", encoding="utf-8") as json_data:
	with open('all_readings.csv', 'rt') as all_data_file:
		try:
			levels_reader1 = csv.reader(all_data_file, delimiter=',')
			csv_data_list = list(levels_reader1)

		except ValueError:
			prRed('process_csv.py error reading file 1')
			
	return(csv_data_list)

def get_subset(list, start_date, end_date, y_value):
	returned_list = []
	for i in range (0, len(list), 1):
		row = []
		if start_date <= list[i][0] <= end_date:
			if y_value == 'day_of_week':
				row.append(datetime.date.fromisoformat(list[i][0]).strftime("%a"))
			elif y_value == 'day_of_month':
				row.append('d' + str(datetime.date.fromisoformat(list[i][0]).strftime("%d")))  # prefix with 'd' so Google API doesn't treat as a number, as tht results in a smoothed line graph 
			elif y_value == 'month':
				row.append(datetime.date.fromisoformat(list[i][0]).strftime("%b"))
			else:
				row.append(list[i][y_value])  # time
			row.append(list[i][2])  # pm value 
			returned_list.append(row)	
	return(returned_list)

def write_subset(list, filename, header):
	with open(filename, mode='w',newline='') as output_file:    # newline = '' for Windows as otherwise it outputs an extra CR
		output_writer = csv.writer(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
		output_writer.writerow(header)
		for i in range (0, len(list), 1):
			output_writer.writerow(list[i])

def write_outage_csv(list1):
	last_record_datetime = datetime.datetime.fromisoformat('1970-01-01 00:00')
	good_delta = datetime.datetime.fromisoformat('1970-01-01 00:20') - datetime.datetime.fromisoformat('1970-01-01 00:00')
	with open('outages.csv', mode='w',newline='') as output_file:    # newline = '' for Windows as otherwise it outputs an extra CR
		output_writer = csv.writer(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
		output_writer.writerow(['outages > 10m','duration [hh:mm]'])

		flag = False
		last_outage_text = ''
		for i in range (len(list1)-1, 0, -1):
			record_datetime = datetime.datetime.fromisoformat(list1[i][0] + ' ' + list1[i][1])
			delta = last_record_datetime - record_datetime  
			if delta > good_delta:
				outage = delta 
				if len(str(outage)) == 7:
					outage_str = '0' + str(outage)[:-3]
				else:
					outage_str = str(outage)[:-3]
				output_writer.writerow([str(record_datetime), outage_str])
				if flag == False:
					last_outage_text = 'last outage: ' + str(record_datetime) + ' for ' + outage_str + ' [hh:mm]' 
					flag = True
#				print (str(i) + ' ' + str(record_datetime) + ' ' + str(delta))
#				print ('len=' + str(len(str(outage))))
			last_record_datetime = record_datetime
		return(last_outage_text)
			
def write_stats(list1):
	lowest_reading 	= 99999
	latest_reading 	= '000'
	highest_reading = '000'
	last_record_datetime = datetime.datetime.fromisoformat(list1[-1][0] + ' ' + list1[-1][1])
	
	for i in range (0, len(list1), 1):
		if  int(list1[i][2]) < lowest_reading:   # string comparison worked up to 999
			lowest_reading = int(list1[i][2])
			lowest_reading_datetime = datetime.datetime.fromisoformat(list1[i][0] + ' ' + list1[i][1])
		if  list1[i][2] > highest_reading:   # these are strings not numbers
			highest_reading = list1[i][2]
			highest_reading_datetime = datetime.datetime.fromisoformat(list1[i][0] + ' ' + list1[i][1])

	num_records = len(list1)
	file_size = num_records * 20.0 / 1000
	num_records_s = str(num_records)
	num_records_f 	= str(num_records_s[0:len(num_records_s)-3]) + ',' +  str(num_records_s[len(num_records_s)-3:len(num_records_s)+1])
	file_size_f = str(file_size)	+ ' kB'
	dl_file_text = num_records_f + ' records, ' + file_size_f  
	
	padded_dow = { 	"Monday" 		: "Monday&nbsp;&nbsp;&nbsp;",
					"Tuesday" 		: "Tuesday&nbsp;&nbsp;",	
					"Wednesday" 	: "Wednesday",	
					"Thursday" 		: "Thursday&nbsp;",	
					"Friday" 		: "Friday&nbsp;&nbsp;&nbsp;",	
					"Saturday" 		: "Saturday&nbsp; ",	
					"Sunday" 		: "Sunday&nbsp;&nbsp;&nbsp;"
				}
	
	line1 = 'last reading:&nbsp;&nbsp;&nbsp;&nbsp;' + list1[-1][2] + 'ppm at ' + list1[-1][1] + ' on ' + padded_dow[last_record_datetime.strftime("%A")] + ' ' + last_record_datetime.strftime("%d") + ' ' + last_record_datetime.strftime("%b") + ' ' + last_record_datetime.strftime("%Y") 
	line2 = 'lowest reading:&nbsp;&nbsp;' + str(lowest_reading) + 'ppm at ' +  lowest_reading_datetime.strftime("%H") + ':' + lowest_reading_datetime.strftime("%M") + ' on ' + padded_dow[lowest_reading_datetime.strftime("%A")] + ' ' + lowest_reading_datetime.strftime("%d") + ' ' + lowest_reading_datetime.strftime("%b") + ' ' + lowest_reading_datetime.strftime("%Y")
	line3 = 'highest reading:&nbsp;' + highest_reading + 'ppm at ' +  highest_reading_datetime.strftime("%H") + ':' + highest_reading_datetime.strftime("%M") + ' on ' + padded_dow[highest_reading_datetime.strftime("%A")] + ' ' + highest_reading_datetime.strftime("%d") + ' ' + highest_reading_datetime.strftime("%b") + ' ' + highest_reading_datetime.strftime("%Y")
		
	stats_dict = {	'line1' : line1,
					'line2' : line2,
					'line3' : line3,
					'last_reading_datetime' : str(last_record_datetime),
					'site_location' : 'Brighton England (sensor is indoors test development platform)',
					'dl_file_text' : dl_file_text,
					'last_reading' : list1[-1][2],
					'lowest_reading' : str(lowest_reading),
					'highest_reading' : highest_reading,
					}
	
#	print (stats_dict)
	with open('stats.json', 'w') as write_file:
		json.dump(stats_dict, write_file, indent=2) 

def	pad_rest_of_day_with_zeros(list1):

	list2 = list1.copy()
	
	lowest_reading = '999'
	for i in range (0, len(list1), 1):
		if  list1[i][1] < lowest_reading:   # these are strings not numbers
			lowest_reading = list1[i][1]
		
	padding_value = str((int(int(lowest_reading)/10))*10)
	print (lowest_reading)
	print ('padding_value')
	print (padding_value)
	
	print (list1)
	
	last_record_datetime = datetime.datetime.fromisoformat('2018-01-01 ' + list1[-1][0])
	end_of_day = last_record_datetime.replace(hour=23).replace(minute=59)
	
	next_ts = last_record_datetime + timedelta(minutes=10)
	while next_ts < end_of_day:
		list2.append([str(next_ts.time())[:-3], padding_value])
		next_ts = next_ts +   timedelta(minutes=10) 
	return(list2)	
	
# MAIN SECTION

list1=read_csv_file()
#sort into date and time
list1.sort(key=lambda x: x[0:1])
#list1=sorted(list1)

todays_date=datetime.date.isoformat(datetime.date.today())
todays_readings=get_subset(list1, todays_date, todays_date, 1)
todays_readings_padded_to_2359=pad_rest_of_day_with_zeros(todays_readings)


write_subset(todays_readings_padded_to_2359, 'todays_readings.csv', ['time','co2_ppm'])

yesterdays_date=datetime.date.isoformat(datetime.date.today() - timedelta(days=1))
yesterdays_readings=get_subset(list1, yesterdays_date, yesterdays_date, 1)
write_subset(yesterdays_readings, 'yesterdays_readings.csv', ['time','co2_ppm'])

day_befores_date=datetime.date.isoformat(datetime.date.today() - timedelta(days=2))
day_befores_readings=get_subset(list1, day_befores_date, day_befores_date, 1)
write_subset(day_befores_readings, 'day_befores_readings.csv', ['time','co2_ppm'])

num_days_since_monday=((datetime.date.today().weekday()))
num_days_to_sunday = 6 - num_days_since_monday
last_monday_week=datetime.date.isoformat(datetime.date.today() - timedelta(weeks=1) - timedelta(days=num_days_since_monday))
last_sunday=datetime.date.isoformat(datetime.date.today() - timedelta(weeks=1) + timedelta(days=num_days_to_sunday))
last_weeks_readings=get_subset(list1, last_monday_week, last_sunday, 'day_of_week')
write_subset(last_weeks_readings, 'last_weeks_readings.csv', ['day','co2_ppm'])

day_of_month=((datetime.date.today().weekday()))
num_days_to_sunday = 6 - num_days_since_monday
last_monday_week=datetime.date.isoformat(datetime.date.today() - timedelta(weeks=1) - timedelta(days=num_days_since_monday))
last_sunday=datetime.date.isoformat(datetime.date.today() - timedelta(weeks=1) + timedelta(days=num_days_to_sunday))
last_weeks_readings=get_subset(list1, last_monday_week, last_sunday, 'day_of_week')
write_subset(last_weeks_readings, 'last_weeks_readings.csv', ['day','co2_ppm'])


two_mondays_ago=datetime.date.isoformat(datetime.date.today() - timedelta(weeks=2) - timedelta(days=num_days_since_monday))
two_sundays_ago=datetime.date.isoformat(datetime.date.today() - timedelta(weeks=2) + timedelta(days=num_days_to_sunday))
week_before_lasts_readings=get_subset(list1, two_mondays_ago, two_sundays_ago, 'day_of_week')
write_subset(week_before_lasts_readings, 'week_before_lasts_readings.csv', ['day','co2_ppm'])

end_of_last_month=datetime.date.today().replace(day=1) - datetime.timedelta (days = 1)
start_of_last_month=end_of_last_month.replace(day=1)
last_months_readings=get_subset(list1, str(start_of_last_month), str(end_of_last_month), 'day_of_month')
write_subset(last_months_readings, 'last_months_readings.csv', ['day','co2_ppm'])

all_historic_readings=get_subset(list1, '2018-11-15', '2999-12-31', 'month')
write_subset(all_historic_readings, 'all_historic_readings.csv', ['month','co2_ppm'])

outage_text=write_outage_csv(list1)
write_stats(list1)

print ("Current year: ", datetime.date.today().strftime("%Y"))
print ("Month of year: ", datetime.date.today().strftime("%m"))
print ("Week number of the year: ", datetime.date.today().strftime("%W"))
print ("Weekday of the week: ", datetime.date.today().strftime("%w"))
print ("Day of year: ", datetime.date.today().strftime("%j"))
print ("Day of the month : ", datetime.date.today().strftime("%d"))
print ("Day of week: ", datetime.date.today().strftime("%A"))
print ("Day of week: ", datetime.date.today().strftime("%a"))
print ("ISO: ",datetime.date.isoformat(datetime.date.today())) 
<file_sep>echo 'a' > alarm_flag_for_telegram_bot.flag
vlc --loop morse_CO2.mp3
