// Extract optional parameters from load_kwargs
date_now = datetime.now().isoformat().split(".")[0]
output_name = load_kwargs.pop("output_name", "NILMTK_FHMM_" + date_now)
resample_seconds = load_kwargs.pop("resample_seconds", 60)
resample_rule = "{:d}S".format(resample_seconds)
timeframes = []
building_path = "/building{}".format(mains.building())
mains_data_location = "{}/elec/meter1".format(building_path)
data_is_available = False
for chunk in mains.power_series(**load_kwargs):
// Check that chunk is sensible size before resampling
if len(chunk) < MIN_CHUNK_LENGTH:
continue
// Record metadata
timeframes.append(chunk.timeframe)
measurement = chunk.name
chunk = chunk.resample(rule=resample_rule)
// Check chunk size *again* after resampling
if len(chunk) < MIN_CHUNK_LENGTH:
continue
// Start disaggregation
predictions = self.disaggregate_chunk(chunk)
for meter in predictions.columns:
data_is_available = True
meter_instance = meter.instance()
cols = pd.MultiIndex.from_tuples([chunk.name])
predicted_power = predictions[[meter]]
output_df = pd.DataFrame(predicted_power)
output_df.columns = pd.MultiIndex.from_tuples([chunk.name])
output_datastore.append("{}/elec/meter{}"
.format(building_path, meter_instance),
output_df)
// Copy mains data to disag output
output_datastore.append(key=mains_data_location,
value=pd.DataFrame(chunk, columns=cols))
if not data_is_available:
return
////////////////////////////////////////////////////////////////////
// Add metadata to output_datastore
// TODO: `preprocessing_applied` for all meters
// TODO: split this metadata code into a separate function
// TODO: submeter measurement should probably be the mains
// measurement we used to train on, not the mains measurement.
// DataSet and MeterDevice metadata:
meter_devices = {
"FHMM": {
"model": "FHMM",
"sample_period": resample_seconds,
"max_sample_period": resample_seconds,
"measurements": [{
"physical_quantity": measurement[0],
"type": measurement[1]
}]
},
"mains": {
"model": "mains",
"sample_period": resample_seconds,
"max_sample_period": resample_seconds,
"measurements": [{
"physical_quantity": measurement[0],
"type": measurement[1]
}]
}
}
merged_timeframes = merge_timeframes(timeframes, gap=resample_seconds)
total_timeframe = TimeFrame(merged_timeframes[0].start,
merged_timeframes[-1].end)
dataset_metadata = {"name": output_name, "date": date_now,
"meter_devices": meter_devices,
"timeframe": total_timeframe.to_dict()}
output_datastore.save_metadata("/", dataset_metadata)
// Building metadata
// Mains meter:
elec_meters = {
1: {
"device_model": "mains",
"site_meter": True,
"data_location": mains_data_location,
"preprocessing_applied": {}, // TODO
"statistics": {
"timeframe": total_timeframe.to_dict()
}
}
}
// TODO: FIX THIS! Ugly hack for now
// Appliances and submeters:
appliances = []
for i, meter in enumerate(self.meters):
meter_instance = meter.instance()
for app in meter.appliances:
appliance = {
"meters": [meter_instance],
"type": app.identifier.type,
"instance": app.identifier.instance
// TODO this `instance` will only be correct when the
// model is trained on the same house as it is tested on.
// https://github.com/nilmtk/nilmtk/issues/194
}
appliances.append(appliance)
elec_meters.update({
meter_instance: {
"device_model": "FHMM",
"submeter_of": 1,
"data_location": ("{}/elec/meter{}"
.format(building_path, meter_instance)),
"preprocessing_applied": {}, // TODO
"statistics": {
"timeframe": total_timeframe.to_dict()
}
}
})
// Setting the name if it exists
if meter.name:
if len(meter.name) > 0:
elec_meters[meter_instance]["name"] = meter.name
building_metadata = {
"instance": mains.building(),
"elec_meters": elec_meters,
"appliances": appliances
After Change
date_now = datetime.now().isoformat().split(".")[0]
output_name = load_kwargs.pop("output_name", "NILMTK_FHMM_" + date_now)
if "resample_seconds" in load_kwargs:
warn(""resample_seconds" is deprecated."
" Please use "sample_period" instead.")
load_kwargs["sample_period"] = load_kwargs.pop("resample_seconds")
load_kwargs.setdefault("sample_period", 60)
resample_seconds = load_kwargs["sample_period"]
timeframes = []
building_path = "/building{}".format(mains.building())
mains_data_location = "{}/elec/meter1".format(building_path)
data_is_available = False
for chunk in mains.power_series(**load_kwargs):
// Check that chunk is sensible size before resampling
if len(chunk) < MIN_CHUNK_LENGTH:
continue
// Record metadata
timeframes.append(chunk.timeframe)
measurement = chunk.name
// Start disaggregation
predictions = self.disaggregate_chunk(chunk)
for meter in predictions.columns:
data_is_available = True
meter_instance = meter.instance()
cols = pd.MultiIndex.from_tuples([chunk.name])
predicted_power = predictions[[meter]]
output_df = pd.DataFrame(predicted_power)
output_df.columns = pd.MultiIndex.from_tuples([chunk.name])
output_datastore.append("{}/elec/meter{}"
.format(building_path, meter_instance),
output_df)
// Copy mains data to disag output
output_datastore.append(key=mains_data_location,
value=pd.DataFrame(chunk, columns=cols))
if not data_is_available:
return
////////////////////////////////////////////////////////////////////
// Add metadata to output_datastore
// TODO: `preprocessing_applied` for all meters
// TODO: split this metadata code into a separate function
// TODO: submeter measurement should probably be the mains
// measurement we used to train on, not the mains measurement.
// DataSet and MeterDevice metadata:
meter_devices = {
"FHMM": {
"model": "FHMM",
"sample_period": resample_seconds,
"max_sample_period": resample_seconds,
"measurements": [{
"physical_quantity": measurement[0],
"type": measurement[1]
}]
},
"mains": {
"model": "mains",
"sample_period": resample_seconds,
"max_sample_period": resample_seconds,
"measurements": [{
"physical_quantity": measurement[0],
"type": measurement[1]
}]
}
}
merged_timeframes = merge_timeframes(timeframes, gap=resample_seconds)
total_timeframe = TimeFrame(merged_timeframes[0].start,
merged_timeframes[-1].end)
dataset_metadata = {"name": output_name, "date": date_now,
"meter_devices": meter_devices,
"timeframe": total_timeframe.to_dict()}
output_datastore.save_metadata("/", dataset_metadata)
// Building metadata
// Mains meter:
elec_meters = {
1: {
"device_model": "mains",
"site_meter": True,
"data_location": mains_data_location,
"preprocessing_applied": {}, // TODO
"statistics": {
"timeframe": total_timeframe.to_dict()
}
}
}
// TODO: FIX THIS! Ugly hack for now
// Appliances and submeters:
appliances = []
for i, meter in enumerate(self.meters):
meter_instance = meter.instance()
for app in meter.appliances:
appliance = {
"meters": [meter_instance],
"type": app.identifier.type,
"instance": app.identifier.instance
// TODO this `instance` will only be correct when the
// model is trained on the same house as it is tested on.
// https://github.com/nilmtk/nilmtk/issues/194
}
appliances.append(appliance)
elec_meters.update({
meter_instance: {
"device_model": "FHMM",
"submeter_of": 1,
"data_location": ("{}/elec/meter{}"
.format(building_path, meter_instance)),
"preprocessing_applied": {}, // TODO
"statistics": {
"timeframe": total_timeframe.to_dict()
}
}
})
// Setting the name if it exists
if meter.name:
if len(meter.name) > 0:
elec_meters[meter_instance]["name"] = meter.name
building_metadata = {
"instance": mains.building(),
"elec_meters": elec_meters,
"appliances": appliances