Thursday, 14 January 2016

Tide Indicator Pi Project #9 - Calculation of Current Tide Completed (No bugs)

The last version I posted, v2.2, turned out not to work for all tide states, due to some maths errors. These have all been fixed and the code seems to work well.

I've think I've finally got the hang of updating to github, so here's the latest code:

tideproject/tidenow3.0.py

This is the output:

(datetime.datetime(2016, 1, 14, 21, 34, 13, 517280), u'10.5')
(datetime.datetime(2016, 1, 15, 4, 9, 13, 518325), u'1.9')
Tide is currently:  falling
Tidal Range =  -8.6
Current Tide :  9.55460304533

Next job is to have it running continuously and outputting to this webpage.

Sunday, 3 January 2016

Tide Indicator Pi Project #8 - Calculation of Current Tide Completed

The program below seems to work!

Output:

('Next: ', (datetime.datetime(2016, 1, 3, 6, 18, 23, 116073), u'4.3'), ' is ', datetime.timedelta(0, 21180, 2472), ' away. /n Previous: ', (datetime.datetime(2016, 1, 2, 23, 49, 23, 115191), u'8.1'), ' was ', datetime.timedelta(0, 2159, 998410), ' ago.')
('Sum of both gaps is ', datetime.timedelta(0, 23340, 882))
('Tide is Currently: ', 'falling')
('tide difference = ', -3.8)
('lower tide value', 4.299999999999999)
('Normalised Time =', 2159, 23340, 0.29060405051843885)
0.958070971113
('Current tide : ', 7.940669690228617)

Code:

#version 1.0
#This program pulls tide data from the ports of Jersey Website
#Under a licence from the UKHO
#
#It then calculates the current tide using a simplified sinusoidal harmonic approximation
#By finding the two tide data points either side of now and working out the current tide height

import urllib2
from bs4 import BeautifulSoup
from time import sleep
import datetime as dt
import math

#open site and grab html

soup = BeautifulSoup(rawhtml, "html.parser")

#get the tide data (it's all in tags)

rawtidedata = soup.findAll('td')

#parse all data points (date, times, heights) to one big list
#format of the list is [day,tm,ht,tm,ht,tm,lt,tm,lt]

n=0
parsedtidedata=[]
for i in rawtidedata:
parsedtidedata.append(rawtidedata[n].get_text())
n += 1

#extract each class of data (day, time , height) to a separate list (there are 10 data items for each day)

tidetimes=[]
tideheights=[]
tideday=[]
lastdayofmonth=int(parsedtidedata[-10])

for n in range(0,lastdayofmonth*10,10):

tideday.append(parsedtidedata[n])
tidetimes.extend([parsedtidedata[n+1],parsedtidedata[n+3],parsedtidedata[n+5],parsedtidedata[n+7]])
tideheights.extend([parsedtidedata[n+2],parsedtidedata[n+4],parsedtidedata[n+6],parsedtidedata[n+8]])

#get time now:

currentTime = dt.datetime.now()

#create a list of all the tide times as datetime objects:

dtTideTimes=[]
tideDataList=[]

for j in range (0,lastdayofmonth*4):
#print tidetimes[j][0:2], tidetimes[j][3:6]
if tidetimes[j]=='**':
dtTideTimes.append('**')
else:

dtTideTimes.append(dt.datetime.now().replace(day=int(j/4+1), hour=int(tidetimes[j][0:2]), minute=int(tidetimes[j][3:5])))

#make a tuple for each data point and add it to a list
tupleHolder =(dtTideTimes[j], tideheights[j])
tideDataList.append(tupleHolder)

#print what we've got so far
# print tideDataList[j]

#find the two closest times in the list to now:

gap1 = abs(tideDataList - currentTime)
gap2 = abs(tideDataList - currentTime)
nearest1 = tideDataList

#print gap1

for j in range (0,lastdayofmonth*4):

if (tideDataList[j] !="**"):
gapx = abs(tideDataList[j] - currentTime)

#check if the data point is the first or second nearest to now.
#Generates the datapoints either side of now

if (gapx <= gap1):
nearest1 = tideDataList[j]
gap1 = gapx
if (gap1 < gapx and gapx <= gap2):
nearest2 = tideDataList[j]
gap2 = gapx

#print (nearest1, gap1)
#print (nearest2, gap2)
#print (gap1+gap2)

#and now the maths begins
#print ('tide height 1 = ', nearest1)
#print ('tide height 2 = ', nearest2)

#need to get them in order of time: (this works)

if nearest1 > nearest2:
nextDataPoint = nearest1
prevDataPoint = nearest2
gapToNext = gap1
gapToPrev = gap2

else:
nextDataPoint = nearest2
prevDataPoint = nearest1
gapToNext = gap2
gapToPrev = gap1

gapSum = gapToNext + gapToPrev

print('Next: ', nextDataPoint,' is ',gapToNext, ' away. /n Previous: ', prevDataPoint, ' was ', gapToPrev, ' ago.')
print('Sum of both gaps is ', gapSum) #this works

#is the tide rising or falling?
tideDifference = float(nextDataPoint)-float(prevDataPoint)

if (tideDifference<0 data-blogger-escaped-0="prev" data-blogger-escaped-:="" data-blogger-escaped-all="" data-blogger-escaped-code="" data-blogger-escaped-currently:="" data-blogger-escaped-currenttide="" data-blogger-escaped-data="" data-blogger-escaped-difference=", tideDifference) #this works

lowerTide = (float(nearest1) + float(nearest2) - abs(tideDifference))/2
print (" data-blogger-escaped-doesn="" data-blogger-escaped-else:="" data-blogger-escaped-falling="" data-blogger-escaped-for="" data-blogger-escaped-ide="" data-blogger-escaped-is="" data-blogger-escaped-lower="" data-blogger-escaped-lowertide="" data-blogger-escaped-math.cos="" data-blogger-escaped-math.pi="" data-blogger-escaped-normalisedtime="" data-blogger-escaped-ormalised="" data-blogger-escaped-pi="next" data-blogger-escaped-print="" data-blogger-escaped-scaled="" data-blogger-escaped-t="" data-blogger-escaped-this="" data-blogger-escaped-tide="" data-blogger-escaped-tidedifference="" data-blogger-escaped-tidestate="" data-blogger-escaped-time=", gapToPrev.seconds, gapSum.seconds, normalisedTime)

print (math.cos(normalisedTime))

if tideState == " data-blogger-escaped-to="" data-blogger-escaped-urrent="" data-blogger-escaped-value="" data-blogger-escaped-work="" data-blogger-escaped-works="">

Saturday, 2 January 2016

Tide Indicator Pi Project #7 - Finding the two tide data points nearest to the current time.

This project is taking ages! I've done a lot since the last post however, but documented very little, so I'll do my best to recall how I got from there to here. You can see all the posts so far here.

The problem in a nutshell: The program needs to get the two tide data points either side of the current time, to work out what the tide is doing now.

Since the last post, the code has been modified to create a list of tuples, with each tuple having two data points (tide time, tide height)

It then works out the gap between each data point and the current time, and tries to store the two nearest times as 'nearest1' and 'nearest2'. Sometime it works:

Time Now:
2015-01-02 16:33

Output:
(datetime.datetime(2016, 1, 2, 17, 52, 40, 854958), u'4.0'),
(datetime.datetime(2016, 1, 2, 11, 9, 40, 854071), u'8.4')

Sometimes it doesn't and misses a point.

#
import urllib2
from bs4 import BeautifulSoup
from time import sleep
import datetime as dt

#open site and grab html

soup = BeautifulSoup(rawhtml, "html.parser")

#get the tide data (it's all in tags)

rawtidedata = soup.findAll('td')

#parse all data points (date, times, heights) to one big list
#format of the list is [day,tm,ht,tm,ht,tm,lt,tm,lt]

n=0
parsedtidedata=[]
for i in rawtidedata:
parsedtidedata.append(rawtidedata[n].get_text())
n += 1

#extract each class of data (day, time , height) to a separate list (there are 10 data items for each day):

tidetimes=[]
tideheights=[]
tideday=[]
lastdayofmonth=int(parsedtidedata[-10])

for n in range(0,lastdayofmonth*10,10):

tideday.append(parsedtidedata[n])
tidetimes.extend([parsedtidedata[n+1],parsedtidedata[n+3],parsedtidedata[n+5],parsedtidedata[n+7]])
tideheights.extend([parsedtidedata[n+2],parsedtidedata[n+4],parsedtidedata[n+6],parsedtidedata[n+8]])

#get time now:

currentTime = dt.datetime.now()

#create a list of all the tide times as datetime objects:

dtTideTimes=[]
tideDataList=[]

for j in range (0,lastdayofmonth*4):
#print tidetimes[j][0:2], tidetimes[j][3:6]
if tidetimes[j]=='**':
dtTideTimes.append('**')
else:
dtTideTimes.append(dt.datetime.now().replace(day=int(j/4+1), hour=int(tidetimes[j][0:2]), minute=int(tidetimes[j][3:5])))

#create a tuple of time and height, and add each tuple to a list

tupleHolder =(dtTideTimes[j], tideheights[j])
tideDataList.append(tupleHolder)

#print what we've got so far

for j in range (0,lastdayofmonth*4):
print tideDataList[j]

#find the two closest data points to now in the list:

gap1 = abs(tideDataList - currentTime)
nearest1 = tideDataList
print gap1

for j in range (0,lastdayofmonth*4):

if (tideDataList[j] !="**"):

gap2 = abs(tideDataList[j] - currentTime)
print tideDataList[j], gap2, nearest1

if (gap2 < gap1):

nearest2 = nearest1
nearest1 = tideDataList[j]
gap1 = gap2

print (nearest1, nearest2)

#this nearly works!!! Gave the two nearest high tides, not nearest high and low.

Portable Power

http://uk.rs-online.com/web/p/lithium-rechargeable-battery-packs/7757504/

Powers a Raspberry Pi with 5V for £8 from RS