In a previous article I sketched the road map for implementing a small web application to present data from a small weather station with the help of PyWWS and the Flot plug-in. In this article we show how to provide data from the pywww/DataStore
module as JSON encoded information that we can use in AJAX calls.
Producing JSON encoded weather data with CherryPy
Our web application is a single web page with some added Javascript that relies on a number of
services that provide JSON encoded data to AJAX calls.
These services are implemented as Python classes within a CherryPy application. The first class we define is called Basic
and its initializer takes a single tz
argument. This will be the timezone used to display data.
class Basic: def __init(self,tz=pytz.timezone('Europe/Amsterdam')): self.tz=tz @cherrypy.expose def default(self,name,_=None,start=None,end=None): start,end = self.verifystartend(start,end) if name in { 'temp_out','hum_out','wind_ave', 'wind_gust','wind_dir','rain'}: return self.getdata(name,start,end)
The crucial method is default()
. It is exposed to the CherryPy engine with the cherrypy.expose
decorator. A exposed method with the name default
will receive any request that cannot be mapped to a more specific name. The name
attribute will hold the final part of the URL. The _
argument will hold a random string that we simply ignore: it is added to any AJAX call by jQuery to prevent the browser from caching results. The start
and stop
arguments are optional and may contain a date/time argument in YYYYMMDDHH
format. If the end
argument is absent, it defaults to now, if the start
argument is absent it defaults to 24 hours before end
. These defaults are calculated by the verifystartend()
method (not shown).
The next check is to see whether name
is one of the known types of data in the DataStore
. If all is well we simply pass the name
, start
and end
arguments to the getdata()
method that we encounter in the next section. The getdata()
method is not part of the Basic
class but will be provided by a mixin class called Service
. The idea is that Basic
and its subclasses provide web application logic to be embedded in CherryPy, while Service
provides an interface to produce JSON encoded data based on the data provided by PyWWS.
We define two subclasses of Basic
. The first is called Hourly
and should return weather data that are the hourly averages. Its initializer takes a weatherdata
argument which should point to the directory where PyWWS stores its data and an optional tz
argument to hold the timezone:
class Hourly(Service,Basic): def __init__(self, weatherdata, tz=pytz.timezone('Europe/Amsterdam')): super().__init__(tz) self.datastore = DataStore.hourly_store self.weatherdata=weatherdataThe most important bit is that
__init__()
creates a datastore
instance variable and initializes it to the hourly_store
class from the DataStore
module. The datastore
and weatherdata
variables will be used by the getdata()
method from the Service
mixin.
The Raw
class is very similar to the Hourly
class only its datastore
variable is initialized to the data_store
class from the DataStore
module which produces non-averaged weather data.
class Raw(Service,Basic): def __init__(self, weatherdata, tz=pytz.timezone('Europe/Amsterdam')): super().__init__(tz) self.datastore = DataStore.data_store self.weatherdata=weatherdataThe
Service
mixin class is where all the hard work is happening. The bulk of the work is done by its getdata()
method. It first creates a suitable instance of a pywws DataStore
and then converts the data it retrieves from this datastore with the dumps
function from the json
module.
def getdata(self,what,start,end): ds=self.datastore(self.weatherdata) return dumps( [( self.millisecondsfromnaiveutc( data['idx']), data[what]) for data in ds[ start.astimezone( Service.utc).replace( tzinfo=None): end.astimezone( Service.utc).replace( tzinfo=None)] ] )The single argument to the
dumps()
function is a list of tuples, each consisting of a timestamp in milliseconds and a floating point value as this is the format that the Flot library expects. This data is retrieved from the datastore with the slice notation: ds[a:b]
will retrieve all the data between a
and b
(if a
and b
are datetime
instances).
All this work was needed to be able to request URLs like http://localhost:8080/temp_out
and receive a response like [[123456,14.1],[123654,14.2],[123789,14.4]]
for example.
In the next installment of this series we will look into the HTML and Javascript code needed to make this web application really work.
This professional hacker is absolutely reliable and I strongly recommend him for any type of hack you require. I know this because I have hired him severally for various hacks and he has never disappointed me nor any of my friends who have hired him too, he can help you with any of the following hacks:
ReplyDelete-Phone hacks (remotely)
-Credit repair
-Bitcoin recovery (any cryptocurrency)
-Make money from home (USA only)
-Social media hacks
-Website hacks
-Erase criminal records (USA & Canada only)
-Grade change
-funds recovery
Email: onlineghosthacker247@ gmail .com
HTML5 Geolocation API Visitor Location
ReplyDeletejQuery File upload progress bar
Google Street View API Example
How to generate QR Code in PHP
PHP code to send email using SMTP
Get Visitor's location and TimeZone
select/deselect all checkboxes using JS
Fibonacci Series Program in PHP
Detect Mobile Devices in PHP