Commit 2b033735 authored by Alan Mitchell's avatar Alan Mitchell

Progress towards conversion to YAML parameters.

parent 3c4898a5
...@@ -72,14 +72,14 @@ class MultiBuildingChartTypeAdmin(admin.ModelAdmin): ...@@ -72,14 +72,14 @@ class MultiBuildingChartTypeAdmin(admin.ModelAdmin):
class ChartBuildingInfoInline(admin.TabularInline): class ChartBuildingInfoInline(admin.TabularInline):
model = ChartBuildingInfo model = ChartBuildingInfo
formfield_overrides = { formfield_overrides = {
models.TextField: {'widget': Textarea(attrs={'rows':1, 'cols':60})}, models.TextField: {'widget': Textarea(attrs={'rows':5, 'cols':40})},
} }
extra = 1 extra = 1
class MultiBuildingChartAdmin(admin.ModelAdmin): class MultiBuildingChartAdmin(admin.ModelAdmin):
inlines = (ChartBuildingInfoInline,) inlines = (ChartBuildingInfoInline,)
formfield_overrides = { formfield_overrides = {
models.TextField: {'widget': Textarea(attrs={'rows':1, 'cols':60})}, models.TextField: {'widget': Textarea(attrs={'rows':6, 'cols':40})},
} }
admin.site.register(Building, BuildingAdmin) admin.site.register(Building, BuildingAdmin)
......
...@@ -4,7 +4,7 @@ Code related to adding calculated fields to the sensor reading database. ...@@ -4,7 +4,7 @@ Code related to adding calculated fields to the sensor reading database.
import time, logging import time, logging
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import transforms import yaml
# Make a logger for this module # Make a logger for this module
_logger = logging.getLogger('bms.' + __name__) _logger = logging.getLogger('bms.' + __name__)
...@@ -164,7 +164,7 @@ class CalculateReadings: ...@@ -164,7 +164,7 @@ class CalculateReadings:
""" """
# Get the function parameters as a dictionary # Get the function parameters as a dictionary
params = transforms.makeKeywordArgs(calcParams) params = yaml.load(calcParams)
# Start a List to hold the sensor IDs that need to be synchronized. Also start # Start a List to hold the sensor IDs that need to be synchronized. Also start
# a separate dictionary that will map the parameter names to these IDs, since the # a separate dictionary that will map the parameter names to these IDs, since the
...@@ -178,13 +178,14 @@ class CalculateReadings: ...@@ -178,13 +178,14 @@ class CalculateReadings:
for nm, id in params.items(): for nm, id in params.items():
if nm.startswith('id_'): if nm.startswith('id_'):
str_id = str(id) # convert id to string
if nm.endswith('_sync'): if nm.endswith('_sync'):
# the sensor to sync on needs to be the first in the ID list. # the sensor to sync on needs to be the first in the ID list.
ids.insert(0, id) ids.insert(0, str_id)
id_dict[nm[3:-5]] = id # strip 'id_' and '_sync' from the name id_dict[nm[3:-5]] = str_id # strip 'id_' and '_sync' from the name
else: else:
ids.append(id) ids.append(str_id)
id_dict[nm[3:]] = id # strip 'id_' from the name id_dict[nm[3:]] = str_id # strip 'id_' from the name
# delete the parameter from the main parameter dictionary, since it is now # delete the parameter from the main parameter dictionary, since it is now
# stored in the id_dict. # stored in the id_dict.
...@@ -270,4 +271,3 @@ class CalcReadingFuncs_base: ...@@ -270,4 +271,3 @@ class CalcReadingFuncs_base:
# past readings in the reading database. # past readings in the reading database.
self.calc_id = None self.calc_id = None
\ No newline at end of file
...@@ -5,46 +5,7 @@ Transform functions for scaling and transforming sensor readings ...@@ -5,46 +5,7 @@ Transform functions for scaling and transforming sensor readings
from __future__ import division from __future__ import division
from math import * from math import *
import sys import sys
import yaml
def makeKeywordArgs(keyword_str):
'''
Turns a string that looks like a set of keyword arguments into a dictionary of those
arguments. Numbers are converted to floats, except the 'id_' exception mentioned below.
Boolean are created if the text looks like a boolean. Otherwise a string is created as
the value. There is a special exception for keyword names that start with the string 'id_':
these are always converted to strings. This conveniently allows sensor ids to be entered
without quotes in parameter lists.
'''
result = {}
keyword_str = keyword_str.strip()
# need to exit if this is a blank string
if len(keyword_str)==0:
return result
for it in keyword_str.strip().split(','):
kw, val = it.split('=')
kw = kw.strip()
val = val.strip()
if kw.startswith('id_'):
# special case of keyword starting with 'id_'. Assume val is a string
# and strip any surrounding quotes of both types.
val = val.strip('"\'')
else:
try:
val = float(val)
except:
if val in ('True', 'true', 'Y', 'y', 'Yes', 'yes'):
val = True
elif val in ('False', 'false', 'N', 'n', 'No', 'no'):
val = False
else:
# must be a string.
# get rid of surrounding quotes of both types.
val = val.strip('"\'')
result[kw] = val
return result
class Transformer: class Transformer:
...@@ -68,7 +29,7 @@ class Transformer: ...@@ -68,7 +29,7 @@ class Transformer:
All three elements of the reading--ts, id, and val--can be transformed by the function. All three elements of the reading--ts, id, and val--can be transformed by the function.
''' '''
params = makeKeywordArgs(trans_params) params = yaml.load(trans_params)
if hasattr(self, trans_func.strip()): if hasattr(self, trans_func.strip()):
the_func = getattr(self, trans_func.strip()) the_func = getattr(self, trans_func.strip())
return the_func(ts, id, val, **params) return the_func(ts, id, val, **params)
...@@ -225,16 +186,3 @@ class Transformer: ...@@ -225,16 +186,3 @@ class Transformer:
# ******** End of Transform Function Section ********** # ******** End of Transform Function Section **********
# ------------ Test functions --------------
def test_kw():
'''
Test function for makeKeywordArgs.
'''
print makeKeywordArgs('abc=True, xyz=23.3, jlk="Hello"')
print makeKeywordArgs("abc=Yes, xyz=23.3, jlk='Hello'")
print makeKeywordArgs("abc=Yes, xyz=23.3, jlk=Hello")
...@@ -62,8 +62,8 @@ class Sensor(models.Model): ...@@ -62,8 +62,8 @@ class Sensor(models.Model):
tran_calc_function = models.CharField("Transform or Calculated Field Function Name", max_length=35, blank=True) tran_calc_function = models.CharField("Transform or Calculated Field Function Name", max_length=35, blank=True)
# the function parameters, if any, for the transform or calculation function above. parameters are # the function parameters, if any, for the transform or calculation function above. parameters are
# entered as one comma-separated string in keyword style, such as 'id_flow="124356", heat_capacity=40.2' # entered in YAML format.
function_parameters = models.TextField("Function Parameters in Keyword form", blank=True) function_parameters = models.TextField("Function Parameters in YAML form", blank=True)
# Calculation order. If this particular calculated field depends on the completion of other calculated fields # Calculation order. If this particular calculated field depends on the completion of other calculated fields
# first, make sure the calculation_order for this field is higher than the fields it depends on. # first, make sure the calculation_order for this field is higher than the fields it depends on.
...@@ -263,9 +263,8 @@ class MultiBuildingChart(models.Model): ...@@ -263,9 +263,8 @@ class MultiBuildingChart(models.Model):
# the general parameters for this chart, if any. These are parameters that are # the general parameters for this chart, if any. These are parameters that are
# *not* associated with a particular building. The parameters are # *not* associated with a particular building. The parameters are
# entered as one comma-separated string in keyword style, # entered in YAML format.
# such as 'id_flow="124356", heat_capacity=40.2' parameters = models.TextField("General Chart Parameters in YAML Form", blank=True)
parameters = models.TextField("General Chart Parameters in Keyword Form", blank=True)
# determines order of Chart displayed in Admin interface # determines order of Chart displayed in Admin interface
sort_order = models.IntegerField(default=999) sort_order = models.IntegerField(default=999)
...@@ -289,9 +288,8 @@ class ChartBuildingInfo(models.Model): ...@@ -289,9 +288,8 @@ class ChartBuildingInfo(models.Model):
building = models.ForeignKey(Building) building = models.ForeignKey(Building)
# the parameters for this chart associated with this building, if any. # the parameters for this chart associated with this building, if any.
# The parameters are entered as one comma-separated string in keyword style, # The parameters are entered in YAML format.
# such as 'id_flow="124356", heat_capacity=40.2' parameters = models.TextField("Chart Parameters in YAML Form", blank=True)
parameters = models.TextField("Chart Parameters in Keyword Form", blank=True)
# determines the order that this building appears in the chart # determines the order that this building appears in the chart
sort_order = models.IntegerField(default=999) sort_order = models.IntegerField(default=999)
......
...@@ -4,8 +4,9 @@ Reports. ...@@ -4,8 +4,9 @@ Reports.
""" """
import time, logging, copy, importlib import time, logging, copy, importlib
from django.conf import settings from django.conf import settings
import yaml
import bmsapp.models, bmsapp.readingdb.bmsdata import bmsapp.models, bmsapp.readingdb.bmsdata
import bmsapp.calcs.transforms, bmsapp.schedule import bmsapp.schedule
import bmsapp.view_util, bmsapp.data_util import bmsapp.view_util, bmsapp.data_util
import chart_config import chart_config
...@@ -126,9 +127,9 @@ class BaseChart(object): ...@@ -126,9 +127,9 @@ class BaseChart(object):
self.request_params = request_params self.request_params = request_params
# for the multi-building chart object, take the keyword parameter string # for the multi-building chart object, take the keyword parameter string
# and convert it to a dictionary. # and convert it to a Python dictionary or list.
if bldg_id == 'multi': if bldg_id == 'multi':
self.chart_params = bmsapp.calcs.transforms.makeKeywordArgs(chart_info.parameters) self.chart_params = yaml.load(chart_info.parameters)
# open the reading database and save it for use by the methods of this object. # open the reading database and save it for use by the methods of this object.
# It is closed automatically in the destructor of the BMSdata class. # It is closed automatically in the destructor of the BMSdata class.
......
import pandas as pd import pandas as pd
import bmsapp.models, bmsapp.data_util, bmsapp.calcs.transforms import yaml
import bmsapp.models, bmsapp.data_util
import basechart import basechart
class NormalizedByDDbyFt2(basechart.BaseChart): class NormalizedByDDbyFt2(basechart.BaseChart):
...@@ -54,7 +55,7 @@ class NormalizedByDDbyFt2(basechart.BaseChart): ...@@ -54,7 +55,7 @@ class NormalizedByDDbyFt2(basechart.BaseChart):
bldg_name = bldg_info.building.title # get the building name bldg_name = bldg_info.building.title # get the building name
# get the parameters associated with this building # get the parameters associated with this building
bldg_params = bmsapp.calcs.transforms.makeKeywordArgs(bldg_info.parameters) bldg_params = yaml.load(bldg_info.parameters)
# get the value records and average into one hour intervals # get the value records and average into one hour intervals
db_recs = self.reading_db.rowsForOneID(bldg_params['id_value'], st_ts, end_ts) db_recs = self.reading_db.rowsForOneID(bldg_params['id_value'], st_ts, end_ts)
......
import bmsapp.models, bmsapp.data_util, bmsapp.calcs.transforms import yaml
import bmsapp.models, bmsapp.data_util
import basechart import basechart
class NormalizedByFt2(basechart.BaseChart): class NormalizedByFt2(basechart.BaseChart):
...@@ -44,7 +45,7 @@ class NormalizedByFt2(basechart.BaseChart): ...@@ -44,7 +45,7 @@ class NormalizedByFt2(basechart.BaseChart):
bldg_name = bldg_info.building.title # get the building name bldg_name = bldg_info.building.title # get the building name
# get the parameters associated with this building # get the parameters associated with this building
bldg_params = bmsapp.calcs.transforms.makeKeywordArgs(bldg_info.parameters) bldg_params = yaml.load(bldg_info.parameters)
# get the value records # get the value records
db_recs = self.reading_db.rowsForOneID(bldg_params['id_value'], st_ts, end_ts) db_recs = self.reading_db.rowsForOneID(bldg_params['id_value'], st_ts, end_ts)
......
"""Converts my original keyword parameters to YAML parameters
"""
import bmsapp.models
import yaml
def makeKeywordArgs(keyword_str):
'''Original function to convert keyword string into dictionary, except special
handling of 'id_' keywords was removed.
'''
result = {}
keyword_str = keyword_str.strip()
# need to exit if this is a blank string
if len(keyword_str)==0:
return result
for it in keyword_str.strip().split(','):
kw, val = it.split('=')
kw = kw.strip()
val = val.strip()
try:
val = float(val)
except:
if val in ('True', 'true', 'Y', 'y', 'Yes', 'yes'):
val = True
elif val in ('False', 'false', 'N', 'n', 'No', 'no'):
val = False
else:
# must be a string.
# get rid of surrounding quotes of both types.
val = val.strip('"\'')
result[kw] = val
return result
def run():
for sen in bmsapp.models.Sensor.objects.exclude(function_parameters=''):
print sen.function_parameters
obj = makeKeywordArgs(str(sen.function_parameters))
sen.function_parameters = yaml.dump(obj, default_flow_style=False)
sen.save()
print
for sen in bmsapp.models.Sensor.objects.exclude(function_parameters=''):
print sen.function_parameters
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment