Timestamp Dataを作成する

generateEspressoRecords.c

このプログラムでは、次のコマンドライン引数を使用します。

  1. Store Id of the coffee store the machine belongs to
  2. The model number of the coffee machine
  3. The percentage that an coffee machine shot fails
  4. The number of shots (on average) the coffee machine makes per hour
  5. The deviation between the shot rate
  6. The clean rate of the machine (in fractions of an hour)

クリーンレートは、コーヒーマシンが1時間に1回のクリーンサイクルを開始するのに要する時間で、単位は時間(hour)です。 したがって、0.2は0.2 * 60 (分) = 12 で、コーヒーマシンのクリーンサイクルの間に約12分がかかることを意味します。

はじめにTimeseries が作成され、GridDBに挿入されます。
GSTimeseries* coffeeMachine = makeEspressoMachine(gridstore, argv[2]);

// Setup Timestamp Column Schema
columnInfo.name = "timestamp"; // Timestamp column
columnInfo.type = GS_TYPE_TIMESTAMP;
….
columnInfo.name = "event_type"; 
// An espresso shot is classified 3 ways: as a SUCCESS, as a FAILURE, or CLEAN cycle 
columnInfo.type = GS_TYPE_INTEGER;
….
columnInfo.name = "temperature"; // Water temperature of the espresso shot
columnInfo.type = GS_TYPE_FLOAT;
….
columnInfo.name = "pressure"; // Water pressure of the current espresso shot
columnInfo.type = GS_TYPE_FLOAT;
….
containerInfo.type = GS_CONTAINER_TIME_SERIES; 

スキーマの作成とGridDBへの挿入は、 他のコンテナの場合と似ています。
サイクル数の更新のため、所属するコーヒーストアコンテナも同様に取得する必要があります。
gsGetCollectionGeneral(gridstore,argv[1],&coffeeStore);

次に、マシンの設定引数が取得、解析され、エスプレッソサイクルの無限ループが開始されます。

espressoCycle(coffeeMachine,coffeeStore,argv[2],shotsPerHour,standard_deviation, \
DEFAULT_TEMPERATURE,DEFAULT_PRESSURE,failure_rate,clean_rate);
srand((unsigned) time(&timer));
direction = rand();
  	pressure_direction = rand();
  	offset = rand() % (MAX_OFFSET + 1);
  	pressure_offset = (float) (rand() % (PRESSURE_OFFSET + 1)) / 100.0; 
  	
if (direction % 2 == 1)
    		offset = offset * -1;
  	
if (pressure_direction % 2 == 1)
    		pressure_offset = pressure_offset * -1.0;
  	pressure = average_pressure + pressure_offset;
  	temperature = average_temperature + offset;
  	
if(currentCycle % secondsToCleanCycle == 0 && currentCycle > 0)
		makeEspressoRecord(basetime,espressoMachine,coffeeStore, \
		serial_num,temperature,pressure,failure_rate,seed,true); 
  	
else
		makeEspressoRecord(basetime,espressoMachine,coffeeStore, \ 
		serial_num,temperature,pressure,failure_rate,seed,false); 
   	
basetime = gsAddTime(basetime,secondsPerShot, GS_TIME_UNIT_SECOND);
seed += secondsPerShot;
currentCycle++; // Move to next cycle
   	
newShotRate = (int) adjustedShotsperHour(shotRate,standard_deviation, seed);
secondsPerShot = calculateSecondsPerShot(newShotRate,standard_deviation, \
seed);
   	
sleep(secondsPerShot); // Wait the waiting time between shots 

ショットレートは、スリープ関数を使用して、エスプレッソショット間の相対待ち時間(秒単位)を決定します。クリーンレートは、クリーンサイクル間の秒数を決定します。makeEspressoRecord関数は現在の時刻のタイムスタンプレコードを生成します。 この関数は、GridDB にタイムスタンプレコードとして挿入されるランダムデータを生成します。 温度と圧力は、乱数発生器から生成される乱数を使い、設定された一定の平均が温度がどれだけオフセット(正または負)されるかを決定します。 ショット間の秒数を決定する方法は、preload.cと同じです。

float recorded_temperature = (float) gaussian_number(average_temperature,SIGMA,seed); 
float recorded_pressure = (float) \ gaussian_number(average_pressure,PRESSURE_SIGMA,seed);
int eventState; // Determine which cycle the current cycle

if(isCleanCycle)
	eventState = CLEAN; 
else 
	eventState = determineEspressoSuccess(failure_rate,seed); 
….
gsSetRowFieldByTimestamp(espressoShotRecord,0,timestamp); // Set the timestamp
gsSetRowFieldByInteger(espressoShotRecord,1,eventState); // Set the eventType
gsSetRowFieldByFloat(espressoShotRecord,2,recorded_temperature); 
gsSetRowFieldByFloat(espressoShotRecord,3,recorded_pressure); 

gsPutRow(espressoMachine,NULL,espressoShotRecord,NULL); // Insert row into TimeSeries
gsCloseRow(&espressoShotRecord); 

updateMachineCycles(coffeeStore,serialNumber,isCleanCycle);

レコードの生成は、まずはgslライブラリを使用してランダムな温度とランダムな圧力を生成し、もしクリーンサイクルの時間ではない場合、別のランダム呼び出しを使用してエスプレッソショットが成功か失敗かを判断します。 これによりすべての行フィールドを設定し、その行をGridDBに挿入することができます。 また、ショットが作られたので、喫茶店のコーヒーマシンレコードも更新する必要があります。

gsGetRowFieldAsInteger(machineRecord,3,&new_cycles); 
gsGetRowFieldAsInteger(machineRecord,4,&clean_cycles); 

gsSetRowFieldByInteger(machineRecord,3,++new_cycles); 

if(resetCleanCycle) // If the last cycle was a clean cycle
	gsSetRowFieldByInteger(machineRecord,4,0); // Reset clean cycle count to zero
else
	gsSetRowFieldByInteger(machineRecord,4,++clean_cycles); // Update clean cycles 

gsPutRow(coffeeStore,NULL,machineRecord,NULL); // Update row

この方法では、コーヒーマシンのシリアル番号を行キーとして使用します。 それぞれの行データは、gsGetRowByStringを使って文字列型で得られる行キーを使って取得できます。それらを増やすことによって新しく(new) クリーン(clean) なサイクルを取得およびセットすることができます。 これらの行フィールドが設定されると、新しい行と更新された行をgsPutRowを使用してGridDBに戻すことができます。

preloadRecords.c

このプログラムは、generateEspressoRecords.cと同じコマンドライン引数をとり、さらに1つの引数(days to preload)をとります。

Days to preload は、プログラムがレコードを生成する現在の時刻の何日前かを決定します。 提供されたマシン設定で5日間を指定すると、プログラムはコーヒーマシンの5日間分のレコードを生成し、すべてをGridDBに挿入します。
レコードは、現在の時刻ではなく過去の時刻であることを除いて、makeEspressoRecord関数と同じ方法で生成されます。

GSTimestamp timeToInsert = gsAddTime(gsCurrentTime(),-1 * days, GS_TIME_UNIT_DAY);
GSTimestamp timeToStopAt = gsCurrentTime();

while(timeToInsert < timeToStopAt){
	if(currentSeconds % secondsToCleanCycle == 0 && currentSeconds > 0)
		makeEspressoRecord(timeToInsert,espressoMachine,coffeeStore,serial_num, \
		average_temperature,average_pressure,failure_rate,currentSeconds,true);

	else
		makeEspressoRecord(timeToInsert,espressoMachine,coffeeStore,serial_num,\ 
		average_temperature,average_pressure,failure_rate,currentSeconds,false);
…..
	timeToInsert = gsAddTime(timeToInsert,secondsPerShot, GS_TIME_UNIT_SECOND);

開始時刻はgsAddTimeを使用して現在の時刻を1日分オフセットします。 停止時間は現在の時間になります。 ショットレートは、生成されるレコードの量と、レコードの時間差を決定します。 レコードが作成されてGridDBに挿入されると、次のレコードのタイムスタンプは、過去のレコードに一定の秒数を追加したものになります。 このプロセスは、挿入する次のタイムスタンプが到達するまで、または現在の時刻よりも長くなるまで繰り返されます。

reset.sh / reset.c

リセットプログラムは、コーヒーチェーンからすべてのデータを削除するためのものです。 これは、すべてのコーヒーストア、コーヒーマシンコンテナ、およびそれらに含まれるすべてのタイムスタンプレコードにまで及びます。 このプロセスは、コーヒーチェーンコンテナを見つけることから始まります。 次にコーヒーチェーン内のすべてのコーヒーストアのすべてのコーヒーストアIDを探します。 そこから各コーヒー店のすべてのコーヒーマシンがGridDBから削除することができます。 コーヒーストアを削除した後にはコーヒーチェーンも削除することができます。

gsGetCollectionGeneral(gridstore,argv[1],&coffee_chain); // Get chain
	….
	while(gsHasNextRow(rowSet)){ // Get all coffee stores in chain
	….
		gsGetNextRow(rowSet,row); // Get coffee store
		gsGetRowFieldAsString(row,0,&container_name); // Obtain store id
		gsGetCollectionGeneral(gridstore,container_name,&coffee_store); // Get store
	…
		  while(gsHasNextRow(innerRs)){ // Get all coffee machines in store
			  gsGetRowFieldAsString(storeEntry,0,&serial_num); // Obtain serial number		  
			  gsDropTimeSeries(gridstore,serial_num); // Drop the corresponding TimeSeries
	….
		gsDropCollection(gridstore,container_name);// Drop coffee store
	….
gsDropCollection(gridstore,argv[1]); // Drop coffee chain

Source Code

以下のリンクから、データ生成クライアントおよびデータ視覚化コンポーネントのアプリケーションおよびそのソースコードをダウンロードできます。

Download: datavisualisation_application.tar.gz