Commit fc262100 authored by claes's avatar claes

Storage environment first version

parent 8a7cd23f
include $(pwre_dir_symbols)
-include $(pwre_kroot)/tools/bld/src/$(os_name)/$(hw_name)/$(type_name)_generic.mk
ifeq ($($(type_name)_generic_mk),)
-include $(pwre_kroot)/tools/bld/src/$(os_name)/$(type_name)_generic.mk
endif
ifeq ($($(type_name)_generic_mk),)
include $(pwre_kroot)/tools/bld/src/$(type_name)_generic.mk
endif
ifndef link_rule_mk
link_rule_mk := 1
link = $(ldxx) $(elinkflags) $(domap) -o $(export_exe) \
$(export_obj) $(objects) $(wb_msg_eobjs) $(rt_msg_eobjs) \
$(pwr_eobj)/rt_io_user.o \
-lpwr_sev -lpwr_rt -lpwr_co $(linkmysql)\
-lpwr_msg_dummy \
-lrpcsvc -lpthread -lm -lrt -ldb_cxx -lz -lcrypt
#-lpwr_wb -lpwr_rt -lpwr_ge -lpwr_flow -lpwr_glow -lpwr_co \
# -L/usr/X11R6/lib -L/usr/local/BerkeleyDB.4.0/lib \
# -L/opt/gnome/lib \
# -lantlr -lImlib -lMrm -lXm -lXpm -lXt -lX11 -lXext -lXp\
# -lXmu -lSM -lICE\
endif
/*
* Proview $Id: rt_sevhistmon.cpp,v 1.1 2008-07-17 11:33:09 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "pwr.h"
#include "pwr_class.h"
#include "pwr_baseclasses.h"
#include "co_cdh.h"
#include "co_error.h"
#include "rt_gdh.h"
#include "rt_qcom.h"
#include "rt_qcom_msg.h"
#include "rt_errh.h"
#include "rt_dshistmon.h"
#include "rt_sev_net.h"
#include "rt_sev_msg.h"
#define sevclient_cQix 121
int rt_dshistmon::init()
{
pwr_tStatus sts;
pwr_tOid hs_oid;
pwr_tAttrRef h_aref;
pwr_tAttrRef uaref;
pwr_tTid a_tid;
unsigned int a_size, a_offset, a_dim;
pwr_tAName hname;
qcom_sQid qid;
qcom_sNode node;
pwr_tNid nid;
sts = gdh_Init( "rt_dshistmon");
// Create a queue to server
qcom_sQattr attr;
qid.qix = sev_eProcSevClient;
qid.nid = 0;
attr.type = qcom_eQtype_private;
attr.quota = 100;
if (!qcom_CreateQ(&sts, &qid, &attr, "SevClient")) {
if ( sts == QCOM__QALLREXIST) {
if ( !qcom_AttachQ(&sts, &qid)) {
if ( !qcom_DeleteQ(&sts, &qid))
co_error(sts);
if ( !qcom_CreateQ(&sts, &qid, &attr, "SevClient"))
co_error(sts);
}
}
else
throw co_error( sts);
}
// Get all qcom nodes
qcom_MyNode( &m_sts, &node);
if ( EVEN(m_sts)) throw co_error(m_sts);
sev_node myn;
myn.nid = node.nid;
strncpy( myn.name, node.name, sizeof(myn.name));
m_nodes.push_back( myn);
for (nid = qcom_cNNid; qcom_NextNode(&sts, &node, nid); nid = node.nid) {
sev_node n;
n.nid = node.nid;
strncpy( n.name, node.name, sizeof(n.name));
m_nodes.push_back( n);
}
// Get all DsHist and DsHistThread objects
for ( sts = gdh_GetClassList( pwr_cClass_DsHistThread, &hs_oid);
ODD(sts);
sts = gdh_GetNextObject( hs_oid, &hs_oid)) {
sev_dshistthread hs;
pwr_sClass_DsHistThread *hs_p;
m_sts = gdh_ObjidToPointer( hs_oid, (void **)&hs_p);
if ( EVEN(m_sts)) throw co_error(m_sts);
hs.oid = hs_oid;
hs.scantime = hs_p->ScanTime;
strncpy( hs.nodename, hs_p->ServerNode, sizeof(hs.nodename));
hs.size = 0;
bool found = false;
for ( unsigned int i = 0; i < m_nodes.size(); i++) {
if ( cdh_NoCaseStrcmp( hs.nodename, m_nodes[i].name) == 0) {
hs.nid = m_nodes[i].nid;
found = true;
break;
}
}
if ( !found) {
pwr_tOName oname;
m_sts = gdh_ObjidToName( hs_oid, oname, sizeof(oname), cdh_mName_volumeStrict);
if ( EVEN(m_sts)) throw co_error(m_sts);
errh_Error( "Unknown nodename, %s", oname);
continue;
}
m_hs.push_back( hs);
}
for ( sts = gdh_GetClassListAttrRef( pwr_cClass_DsHist, &h_aref);
ODD(sts);
sts = gdh_GetNextAttrRef( pwr_cClass_DsHist, &h_aref, &h_aref)) {
sev_dshist h;
pwr_sClass_DsHist *h_p;
int hs_idx;
m_sts = gdh_AttrRefToPointer( &h_aref, (void **)&h_p);
if ( EVEN(m_sts)) throw co_error(m_sts);
h.aref = h_p->Attribute;
m_sts = gdh_AttrrefToName( &h_aref, hname, sizeof(hname), cdh_mName_volumeStrict);
if ( EVEN(m_sts)) throw co_error(m_sts);
hs_idx = -1;
for ( int i = 0; i < (int) m_hs.size(); i++) {
if ( cdh_ObjidIsEqual( h_p->ThreadObject, m_hs[i].oid)) {
hs_idx = i;
break;
}
}
if ( hs_idx == -1) {
errh_Error( "Invalid HistServerObject %s", hname);
continue;
}
m_sts = gdh_GetAttributeCharAttrref( &h_p->Attribute, &a_tid, &a_size, &a_offset, &a_dim);
if ( EVEN(m_sts)) {
errh_Error( "Invalid DsHist Attribute %s", hname);
continue;
}
h.sevid.nid = m_nodes[0].nid;
h.sevid.rix = m_next_rix++;
h.storagetime = h_p->StorageTime;
strncpy( h.description, h_p->Description, sizeof(h.description));
// Get unit from attribute object
sts = gdh_ArefANameToAref( &h_p->Attribute, "Unit", &uaref);
if ( ODD(sts)) {
sts = gdh_GetObjectInfoAttrref( &uaref, &h.unit, sizeof(h.unit));
if ( EVEN(sts))
strcpy( h.unit, "");
}
else
strcpy( h.unit, "");
h.type = (pwr_eType) a_tid;
h.size = a_size;
h.scantime = m_hs[hs_idx].scantime;
switch ( h.type) {
case pwr_eType_Int64:
case pwr_eType_Int32:
case pwr_eType_Int16:
case pwr_eType_Int8:
case pwr_eType_UInt64:
case pwr_eType_UInt32:
case pwr_eType_UInt16:
case pwr_eType_UInt8:
case pwr_eType_Float32:
case pwr_eType_Float64:
case pwr_eType_String:
case pwr_eType_Time:
break;
default:
errh_Error( "Invalid DsHist Attribute type %s", hname);
continue;
}
m_sts = gdh_AttrrefToName( &h_p->Attribute, h.aname, sizeof(h.aname), cdh_mName_volumeStrict);
if ( EVEN(m_sts)) throw co_error(m_sts);
m_sts = gdh_RefObjectInfo( h.aname, &h.datap, &h.refid, h.size);
if ( EVEN(m_sts)) {
errh_Error( "Unable to link to Attribute %s", h.aname);
continue;
}
m_hs[hs_idx].size += h.size;
m_hs[hs_idx].dshistlist.push_back(h);
}
connect();
return 1;
}
int rt_dshistmon::close()
{
for ( unsigned int i = 0; i < m_hs.size(); i++) {
for ( unsigned int j = 0; j < m_hs[i].dshistlist.size(); j++)
gdh_UnrefObjectInfo( m_hs[i].dshistlist[j].refid);
}
m_hs.clear();
return 1;
}
int rt_dshistmon::send_data()
{
qcom_sQid tgt;
qcom_sPut put;
pwr_tStatus sts, lsts;
int msize;
sev_sMsgHistDataStore *msg;
sev_sHistData *dp;
int stime;
for ( unsigned int i = 0; i < m_hs.size(); i++) {
stime = int(m_hs[i].scantime + 0.5);
if ( !stime || m_loopcnt % stime != 0)
continue;
msize = m_hs[i].dshistlist.size() * (sizeof(*dp) - sizeof(dp->data)) + m_hs[i].size;
msize += sizeof(*msg) - sizeof(msg->Data);
msg = (sev_sMsgHistDataStore *) qcom_Alloc(&lsts, msize);
put.size = msize;
put.data = msg;
msg->Type = sev_eMsgType_HistDataStore;
clock_gettime( CLOCK_REALTIME, &msg->Time);
dp = (sev_sHistData *) &msg->Data;
for ( unsigned int j = 0; j < m_hs[i].dshistlist.size(); j++) {
dp->sevid = m_hs[i].dshistlist[j].sevid;
dp->type = m_hs[i].dshistlist[j].type;
dp->size = m_hs[i].dshistlist[j].size;
memcpy( &dp->data, m_hs[i].dshistlist[j].datap, dp->size);
dp = (sev_sHistData *)((char *)dp + sizeof( *dp) - sizeof(dp->data) + dp->size);
}
tgt.nid = m_hs[i].nid;
tgt.qix = sev_eProcSevServer;
put.reply.nid = m_nodes[0].nid;
put.reply.qix = sev_eProcSevClient;
put.type.b = (qcom_eBtype) sev_cMsgClass;
put.type.s = (qcom_eStype) sev_eMsgType_HistDataStore;
put.msg_id = m_msg_id++;
if ( !qcom_Put( &sts, &tgt, &put)) {
qcom_Free( &sts, put.data);
continue;
}
}
return 1;
}
int rt_dshistmon::connect()
{
sev_sMsgAny *msg;
qcom_sQid tgt;
qcom_sPut put;
pwr_tStatus sts, lsts;
for ( unsigned int i = 0; i < m_nodes.size(); i++) {
// Check if this node should be connected
bool found = false;
for ( unsigned int j = 0; j < m_hs.size(); j++) {
if ( cdh_NoCaseStrcmp( m_nodes[i].name, m_hs[j].nodename) == 0) {
found = true;
break;
}
}
if ( !found)
continue;
tgt.nid = m_nodes[i].nid;
tgt.qix = sev_eProcSevServer;
put.reply.nid = m_nodes[0].nid;
put.reply.qix = sev_eProcSevClient;
put.type.b = (qcom_eBtype) sev_cMsgClass;
put.type.s = (qcom_eStype) sev_eMsgType_NodeUp;
put.msg_id = m_msg_id++;
put.size = sizeof(*msg);
msg = (sev_sMsgAny *) qcom_Alloc(&lsts, put.size);
put.data = msg;
msg->Type = sev_eMsgType_NodeUp;
if ( !qcom_Put( &sts, &tgt, &put)) {
qcom_Free( &sts, put.data);
}
}
return 1;
}
int rt_dshistmon::send_itemlist( pwr_tNid nid)
{
int item_cnt = 0;
qcom_sQid tgt;
qcom_sPut put;
pwr_tStatus sts, lsts;
int size;
pwr_tAName aname;
char *s;
// Count items for this node
for ( unsigned int i = 0; i < m_hs.size(); i++) {
if ( nid == m_hs[i].nid)
item_cnt += m_hs[i].dshistlist.size();
}
if ( item_cnt == 0)
return 1;
size = sizeof(sev_sMsgHistItems) + (item_cnt - 1) * sizeof(sev_sHistItem);
put.size = size;
put.data = qcom_Alloc(&lsts, put.size);
((sev_sMsgHistItems *)put.data)->Type = sev_eMsgType_HistItems;
((sev_sMsgHistItems *)put.data)->Status = SEV__SUCCESS;
int k = 0;
for ( unsigned int i = 0; i < m_hs.size(); i++) {
if ( nid == m_hs[i].nid) {
for ( unsigned int j = 0; j < m_hs[i].dshistlist.size(); j++) {
((sev_sMsgHistItems *)put.data)->Items[k].oid = m_hs[i].dshistlist[j].aref.Objid;
strcpy( aname, m_hs[i].dshistlist[j].aname);
s = strchr( aname, '.');
if ( !s)
continue;
*s = 0;
strcpy( ((sev_sMsgHistItems *)put.data)->Items[k].oname, aname);
strcpy( ((sev_sMsgHistItems *)put.data)->Items[k].aname, s + 1);
((sev_sMsgHistItems *)put.data)->Items[k].storagetime = m_hs[i].dshistlist[j].storagetime;
((sev_sMsgHistItems *)put.data)->Items[k].type = m_hs[i].dshistlist[j].type;
((sev_sMsgHistItems *)put.data)->Items[k].size = m_hs[i].dshistlist[j].size;
((sev_sMsgHistItems *)put.data)->Items[k].sevid = m_hs[i].dshistlist[j].sevid;
strncpy( ((sev_sMsgHistItems *)put.data)->Items[k].description,
m_hs[i].dshistlist[j].description,
sizeof(((sev_sMsgHistItems *)put.data)->Items[0].description));
strncpy( ((sev_sMsgHistItems *)put.data)->Items[k].unit,
m_hs[i].dshistlist[j].unit,
sizeof(((sev_sMsgHistItems *)put.data)->Items[0].unit));
((sev_sMsgHistItems *)put.data)->Items[k].scantime = m_hs[i].dshistlist[j].scantime;
k++;
}
}
}
tgt.nid = nid;
tgt.qix = sev_eProcSevServer;
put.reply.nid = m_nodes[0].nid;
put.reply.qix = sev_eProcSevClient;
put.type.b = (qcom_eBtype) sev_cMsgClass;
put.type.s = (qcom_eStype) sev_eMsgType_HistItems;
put.msg_id = m_msg_id++;
if ( !qcom_Put( &sts, &tgt, &put)) {
qcom_Free( &sts, put.data);
return 0;
}
return 1;
}
int rt_dshistmon::mainloop()
{
qcom_sQid qid;
int tmo = 1000;
qcom_sGet get;
void *mp;
pwr_tStatus sts;
qid.nid = 0;
qid.qix = sev_eProcSevClient;
for (;;) {
memset( &get, 0, sizeof(get));
mp = qcom_Get(&sts, &qid, &get, tmo);
if ( sts == QCOM__TMO || !mp) {
m_loopcnt++;
send_data();
continue;
}
switch (get.type.b) {
case sev_cMsgClass:
printf( "Message received\n");
switch ( get.type.s) {
case sev_eMsgType_NodeUp:
case sev_eMsgType_HistItemsRequest:
send_itemlist( get.sender.nid);
break;
default: ;
}
break;
default: ;
}
qcom_Free( &sts, mp);
}
}
int main()
{
rt_dshistmon client;
client.init();
client.mainloop();
client.close();
}
/*
* Proview $Id: rt_sevhistmon.h,v 1.1 2008-07-17 11:33:09 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef rt_dshistmon_h
#define rt_dshistmon_h
#include <vector.h>
#include "pwr.h"
#include "pwr_class.h"
class sev_dshist {
public:
pwr_tAttrRef aref;
pwr_tAName aname;
pwr_tRefId refid;
void *datap;
pwr_tDeltaTime storagetime;
pwr_eType type;
unsigned int size;
pwr_tRefId sevid;
pwr_tString80 description;
pwr_tString16 unit;
pwr_tFloat32 scantime;
};
class sev_dshistthread {
public:
pwr_tOid oid;
pwr_tFloat32 scantime;
char nodename[80];
pwr_tNid nid;
unsigned int size;
vector<sev_dshist> dshistlist;
};
class sev_node {
public:
pwr_tNid nid;
char name[80];
};
class rt_dshistmon {
public:
rt_dshistmon() : m_msg_id(0), m_next_rix(0), m_loopcnt(0) {}
pwr_tStatus m_sts;
vector<sev_dshistthread> m_hs;
vector<sev_node> m_nodes;
unsigned int m_msg_id;
unsigned int m_next_rix;
unsigned int m_loopcnt;
int init();
int close();
int mainloop();
int connect();
int send_itemlist( pwr_tNid nid);
int send_data();
};
#endif
/*
* Proview $Id: rt_sev_net.h,v 1.1 2008-07-17 11:33:59 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef rt_sev_net_h
#define rt_sev_net_h
#include "pwr.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define sev_eProcSevClient 121
#define sev_eProcSevServer 122
#define sev_cMsgClass 201
typedef enum {
sev_eMsgType_NodeUp,
sev_eMsgType_HistItemsRequest,
sev_eMsgType_HistItems,
sev_eMsgType_HistDataStore,
sev_eMsgType_HistDataGetRequest,
sev_eMsgType_HistDataGet,
} sev_eMsgType;
typedef struct {
pwr_tOid oid;
pwr_tOName oname;
pwr_tOName aname;
pwr_tDeltaTime storagetime;
pwr_eType type;
unsigned int size;
pwr_tRefId sevid;
pwr_tString80 description;
pwr_tString16 unit;
pwr_tFloat32 scantime;
} sev_sHistItem;
typedef struct {
pwr_tRefId sevid;
pwr_eType type;
unsigned int size;
int data[1];
} sev_sHistData;
// Message types
typedef struct {
sev_eMsgType Type;
} sev_sMsgAny;
typedef struct {
sev_eMsgType Type;
pwr_tStatus Status;
sev_sHistItem Items[1];
} sev_sMsgHistItems;
typedef struct {
sev_eMsgType Type;
pwr_tTime Time;
int Data[1];
} sev_sMsgHistDataStore;
typedef struct {
sev_eMsgType Type;
pwr_tOid Oid;
pwr_tOName AName;
pwr_tTime StartTime;
pwr_tTime EndTime;
int NumPoints;
} sev_sMsgHistDataGetRequest;
typedef struct {
sev_eMsgType Type;
pwr_tOid Oid;
pwr_tOName AName;
pwr_tStatus Status;
int NumPoints;
pwr_eType VType;
unsigned int VSize;
int Data[1];
} sev_sMsgHistDataGet;
#ifdef __cplusplus
}
#endif
#endif
/*
* Proview $Id: rt_sevcli.c,v 1.1 2008-07-17 11:33:59 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "pwr.h"
#include "co_cdh.h"
#include "co_time.h"
#include "rt_qcom.h"
#include "rt_qcom_msg.h"
#include "rt_sev_msg.h"
#include "rt_sevcli.h"
#include "rt_sev_net.h"
int sevcli_init( pwr_tStatus *sts, sevcli_tCtx *ctx)
{
// Create a queue to server
qcom_sQattr attr;
*ctx = calloc( 1, sizeof(sevcli_sCtx));
(*ctx)->qid.qix = 0;
(*ctx)->qid.nid = 0;
attr.type = qcom_eQtype_private;
attr.quota = 100;
if (!qcom_CreateQ(sts, &(*ctx)->qid, &attr, "SevXtt")) {
return 0;
}
*sts = SEV__SUCCESS;
return 1;
}
int sevcli_close( pwr_tStatus *sts, sevcli_tCtx ctx)
{
// Delete queue
if (!qcom_DeleteQ( sts, &ctx->qid)) {
return 0;
}
free( ctx);
*sts = SEV__SUCCESS;
return 1;
}
void sevcli_set_servernid( sevcli_tCtx ctx, pwr_tNid nid)
{
ctx->server = nid;
}
int sevcli_set_servernode( pwr_tStatus *sts, sevcli_tCtx ctx, char *nodename)
{
qcom_sNode node;
pwr_tNid nid;
if ( !nodename || strcmp( nodename, "") == 0) {
ctx->server = ctx->qid.nid;
*sts = SEV__SUCCESS;
return 1;
}
// Try this node
qcom_MyNode( sts, &node);
if ( EVEN(*sts)) return 0;
if ( cdh_NoCaseStrcmp( node.name, nodename) == 0) {
ctx->server = node.nid;
*sts = SEV__SUCCESS;
return 1;
}
// Try other qcom nodes
for (nid = qcom_cNNid; qcom_NextNode(sts, &node, nid); nid = node.nid) {
if ( cdh_NoCaseStrcmp( nodename, node.name) == 0) {
ctx->server = node.nid;
*sts = SEV__SUCCESS;
return 1;
}
}
*sts = SEV__NOSUCHNODE;
return 0;
}
int sevcli_get_itemlist( pwr_tStatus *sts, sevcli_tCtx ctx, sevcli_sHistItem **list,
unsigned int *cnt)
{
sev_sMsgAny *msg;
qcom_sQid tgt;
qcom_sPut put;
pwr_tStatus lsts;
int tmo = 1000;
qcom_sGet get;
sevcli_sHistItem *lp;
int i;
if ( ctx->server)
tgt.nid = ctx->server;
else
tgt.nid = ctx->qid.nid;
tgt.qix = sev_eProcSevServer;
put.reply = ctx->qid;
put.type.b = (qcom_eBtype) sev_cMsgClass;
put.type.s = (qcom_eStype) sev_eMsgType_HistItemsRequest;
put.msg_id = ctx->msg_id++;
put.size = sizeof(*msg);
msg = (sev_sMsgAny *) qcom_Alloc( sts, put.size);
put.data = msg;
msg->Type = sev_eMsgType_HistItemsRequest;
if ( !qcom_Put( sts, &tgt, &put)) {
qcom_Free( &lsts, put.data);
return 0;
}
sev_sMsgHistItems *rmsg;
memset( &get, 0, sizeof(get));
for (;;) {
rmsg = (sev_sMsgHistItems *) qcom_Get( sts, &ctx->qid, &get, tmo);
if ( *sts == QCOM__TMO || !rmsg) {
return 0;
}
if ( get.type.b == sev_cMsgClass &&
get.type.s == (qcom_eStype) sev_eMsgType_HistItems)
break;
qcom_Free( sts, rmsg);
}
*sts = rmsg->Status;
if ( EVEN(*sts))
return 0;
int item_cnt = (get.size - sizeof(sev_sMsgHistItems)) / sizeof(sev_sHistItem) + 1;
lp = (sevcli_sHistItem *) calloc( item_cnt, sizeof(sevcli_sHistItem));
for ( i = 0; i < item_cnt; i++) {
lp[i].oid = rmsg->Items[i].oid;
strncpy( lp[i].oname, rmsg->Items[i].oname, sizeof(lp[0].oname));
strncpy( lp[i].aname, rmsg->Items[i].aname, sizeof(lp[0].aname));
lp[i].storagetime = rmsg->Items[i].storagetime;
lp[i].type = rmsg->Items[i].type;
lp[i].size = rmsg->Items[i].size;
strncpy( lp[i].description, rmsg->Items[i].description, sizeof(lp[0].description));
strncpy( lp[i].unit, rmsg->Items[i].unit, sizeof(lp[0].unit));
lp[i].scantime = rmsg->Items[i].scantime;
}
qcom_Free( sts, rmsg);
*cnt = item_cnt;
*list = lp;
*sts = SEV__SUCCESS;
return 1;
}
int sevcli_get_itemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid,
char *aname, pwr_tTime starttime, pwr_tTime endtime, int numpoints,
pwr_tTime **tbuf, void **vbuf, int *rows,
pwr_eType *vtype, unsigned int *vsize)
{
sev_sMsgHistDataGetRequest *msg;
qcom_sQid tgt;
qcom_sPut put;
int tmo = 10000;
qcom_sGet get;
pwr_tStatus lsts;
if ( ctx->server)
tgt.nid = ctx->server;
else
tgt.nid = ctx->qid.nid;
tgt.qix = sev_eProcSevServer;
put.reply = ctx->qid;
put.type.b = (qcom_eBtype) sev_cMsgClass;
put.type.s = (qcom_eStype) sev_eMsgType_HistDataGetRequest;
put.msg_id = ctx->msg_id++;
put.size = sizeof(*msg);
msg = (sev_sMsgHistDataGetRequest *) qcom_Alloc( sts, put.size);
put.data = msg;
msg->Type = sev_eMsgType_HistDataGetRequest;
msg->Oid = oid;
strncpy( msg->AName, aname, sizeof(msg->AName));
msg->StartTime = starttime;
msg->EndTime = endtime;
msg->NumPoints = numpoints;
if ( !qcom_Put( sts, &tgt, &put)) {
qcom_Free( &lsts, put.data);
return 0;
}
sev_sMsgHistDataGet *rmsg;
memset( &get, 0, sizeof(get));
for (;;) {
rmsg = (sev_sMsgHistDataGet *) qcom_Get(sts, &ctx->qid, &get, tmo);
if ( *sts == QCOM__TMO || !rmsg)
return 0;
if ( get.type.b == sev_cMsgClass &&
get.type.s == (qcom_eStype) sev_eMsgType_HistDataGet &&
cdh_ObjidIsEqual( oid, rmsg->Oid) &&
cdh_NoCaseStrcmp( aname, rmsg->AName) == 0)
break;
qcom_Free( sts, rmsg);
}
*sts = rmsg->Status;
if ( EVEN(*sts))
return 0;
int item_cnt = rmsg->NumPoints;
*tbuf = malloc( item_cnt * sizeof(pwr_tTime));
*vbuf = malloc( item_cnt * rmsg->VSize);
memcpy( *tbuf, &rmsg->Data, item_cnt * sizeof(pwr_tTime));
memcpy( *vbuf, (char *)&rmsg->Data + item_cnt * sizeof(pwr_tTime), item_cnt * rmsg->VSize);
*rows = item_cnt;
*vtype = rmsg->VType;
*vsize = rmsg->VSize;
qcom_Free( sts, rmsg);
*sts = SEV__SUCCESS;
return 1;
}
/*
* Proview $Id: rt_sevcli.h,v 1.1 2008-07-17 11:33:59 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef rt_sevcli_h
#define rt_sevcli_h
/* rt_sevcli.h -- Storage client */
#ifndef pwr_h
# include "pwr.h"
#endif
#ifndef rt_qcom_h
# include "rt_qcom.h"
#endif
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct {
qcom_sQid qid;
pwr_tNid server;
unsigned int msg_id;
} sevcli_sCtx, *sevcli_tCtx;
typedef struct {
pwr_tOid oid;
pwr_tAName oname;
pwr_tAName aname;
pwr_tDeltaTime storagetime;
pwr_eType type;
unsigned int size;
pwr_tString80 description;
pwr_tString16 unit;
pwr_tFloat32 scantime;
} sevcli_sHistItem;
int sevcli_init( pwr_tStatus *sts, sevcli_tCtx *ctx);
int sevcli_close( pwr_tStatus *sts, sevcli_tCtx ctx);
void sevcli_set_servernid( sevcli_tCtx ctx, pwr_tNid nid);
int sevcli_set_servernode( pwr_tStatus *sts, sevcli_tCtx ctx, char *nodename);
int sevcli_get_itemlist( pwr_tStatus *sts, sevcli_tCtx ctx,
sevcli_sHistItem **list, unsigned int *cnt);
int sevcli_get_itemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid,
char *aname, pwr_tTime starttime, pwr_tTime endtime, int numpoints,
pwr_tTime **tbuf, void **vbuf, int *rows,
pwr_eType *vtype, unsigned int *vsize);
#ifdef __cplusplus
}
#endif
#endif
!
! Proview $Id: rt_sev_msg.msg,v 1.1 2008-07-17 11:38:21 claes Exp $
! Copyright (C) 2005 SSAB Oxelösund AB.
!
! This program is free software; you can redistribute it and/or
! modify it under the terms of the GNU General Public License as
! published by the Free Software Foundation, either version 2 of
! the License, or (at your option) any later version.
!
! This program is distributed in the hope that it will be useful
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with the program, if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
!
! rt_sev_msg.msg -- <short description>
!
.facility SEV,25 /prefix = SEV__
success <Successful completion> /succ
dberror <Database error> /error
nosuchitem <No such item exists> /error
nosuchnode <No such node exists> /error
curvetype <Uable to draw a curve for this type> /error
nodatatime <No data found in this time interval> /error
noitems <No items found> /error
.end
!
! Proview $Id: pwrb_c_dshist.wb_load,v 1.3 2005-09-01 14:58:01 claes Exp $
! Proview $Id: pwrb_c_dshist.wb_load,v 1.4 2008-07-17 11:36:41 claes Exp $
! Copyright (C) 2005 SSAB Oxelsund AB.
!
! This program is free software; you can redistribute it and/or
......@@ -20,12 +20,13 @@
!
SObject pwrb:Class
!/**
! @Version 1.0
! @Version 2.0
! @Group PlantConfiguration,DsHist
! @Summary Configures historical data storage for a value.
! Configures historical data storage for a scalar
! quantity or element in a one-dimensional vector. (Datastorage
! History).
!
! Historical data storage is an option in PROVIEW/R.
! In a relational database, data resides in
! two-dimensional tables known as relations. A relation
! consist of rows and columns.
......@@ -33,14 +34,17 @@ SObject pwrb:Class
! The DsHist object specifies which quantity is to be
! stored and in which relation. Up to three different
! relations can be specified.
! Hints
! Hints
!
! If the storage concern signal values DsHist is
! configured in the development environment often direct
! below the current signal object.
!
! See Also
! DsHistServer.
! @b See also
! @classlink DsHistThread pwrb_dshistthread.html
! @classlink DsHistMonitor pwrb_dshistmonitor.html
! @classlink DsHistServer pwrb_dshistserver.html
!*/
Object DsHist $ClassDef 106
Body SysBody
......@@ -51,6 +55,9 @@ SObject pwrb:Class
Body SysBody
Attr StructName = "DsHist"
EndBody
!/**
! Optional desription.
!*/
Object Description $Attribute 1
Body SysBody
Attr TypeRef = "pwrs:Type-$String80"
......@@ -58,27 +65,36 @@ SObject pwrb:Class
EndObject
!/**
! Specifies the complete name of the attribute whose
! value is to be stored. The attribute has to be any of
! the types: pwr_tBoolean, pwr_tFloat32, pwr_tInt8,
! pwr_tInt16, or pwr_tInt32.
! The value is always stored as pwr_tFloat32.
! value is to be stored.
!*/
Object Attribute $Attribute 2
Body SysBody
Attr TypeRef = "pwrs:Type-$AttrRef"
EndBody
EndObject
Object HistServerObject $Attribute 3
!/**
! DsHistThread object that specifies the storage scantime
! and in which server the data is stored.
!*/
Object ThreadObject $Attribute 3
Body SysBody
Attr TypeRef = "pwrs:Type-$Objid"
Attr Flags |= PWR_MASK_ARRAY
Attr Elements = 3
EndBody
EndObject
!/**
! The attribute is intended for use in the future.
! Time the data will be stored in the database.
! Data that is older than this time will be removed from
! the database by a garbage collector.
!*/
Object DeadBand $Attribute 4
Object StorageTime $Attribute 4
Body SysBody
Attr TypeRef = "pwrs:Type-$DeltaTime"
EndBody
EndObject
!/**
! Not yet implemented.
!*/
Object DeadBand $Attribute 5
Body SysBody
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
......@@ -99,5 +115,20 @@ SObject pwrb:Class
Attr MethodName = "DsHist-PostMove"
EndBody
EndObject
Object ConfiguratorPoson $Menu
Object Pointed $Menu
Object ConnectThread $MenuButton
Body SysBody
Attr ButtonName = "Connect DsHistThread"
Attr MethodName = "$Objid-Connect"
Attr MethodArguments[0] = "ThreadObject"
Attr MethodArguments[1] = "DsHistThread"
Attr FilterName = "$Objid-IsOkConnect"
Attr FilterArguments[0] = "ThreadObject"
Attr FilterArguments[1] = "DsHistThread"
EndBody
EndObject
EndObject
EndObject
EndObject
EndSObject
!
! Proview $Id: pwrb_c_dshistmonitor.wb_load,v 1.1 2008-07-17 11:37:57 claes Exp $
! Copyright (C) 2005 SSAB Oxelsund AB.
!
! This program is free software; you can redistribute it and/or
! modify it under the terms of the GNU General Public License as
! published by the Free Software Foundation, either version 2 of
! the License, or (at your option) any later version.
!
! This program is distributed in the hope that it will be useful
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with the program, if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
!
! pwrb_c_dshistmonitor.wb_load -- Defines the class DsHistMonitor.
!
SObject pwrb:Class
!/**
! @Version 1.0
! @Group Servers,NodeConfiguration
! Configures the DsHist monitor process.
!
! The DsHist monitor process keeps track of all DsHist objects
! in the current node. The process is divided into threads that
! collect data with a specific scantime and sends to the specified
! database server. The threads are specified by DsHistThread objects
! that reside under the DsHistMonitor object in the node hierarchy.
!
! @b See also
! @classlink DsHistThread pwrb_dshistthread.html
! @classlink DsHist pwrb_dshist.html
! @classlink DsHistServer pwrb_dshistserver.html
!*/
Object DsHistMonitor $ClassDef 534
Body SysBody
Attr Editor = pwr_eEditor_AttrEd
Attr Method = pwr_eMethod_Standard
EndBody
Object RtBody $ObjBodyDef 1
Body SysBody
Attr StructName = "DsHistMonitor"
EndBody
!/**
! Optional description.
!*/
Object Description $Attribute 1
Body SysBody
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
EndObject
Object PostCreate $DbCallBack
Body SysBody
Attr MethodName = "DsHistMonitor-PostCreate"
EndBody
EndObject
EndObject
EndSObject
!
! Proview $Id: pwrb_c_dshistserver.wb_load,v 1.4 2005-09-01 14:58:01 claes Exp $
! Proview $Id: pwrb_c_dshistserver.wb_load,v 1.5 2008-07-17 11:36:41 claes Exp $
! Copyright (C) 2005 SSAB Oxelösund AB.
!
! This program is free software; you can redistribute it and/or
......@@ -16,39 +16,29 @@
! along with the program, if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
!
! pwrb_c_dshistserver.wb_load -- Defines the class DsHistServer.
! pwrb_c_dshistmonitor.wb_load -- Defines the class DsHistMonitor.
!
SObject pwrb:Class
!/**
! @Version 1.0
! @Group Servers,NodeConfiguration
! Configures the server for historical data storage. (Datasto
! History Server).
! Configures the DsHist server process.
!
! Historical data storage is an option in PROVIEW/R.
! Data storage is done in a relational database, Rdb. The
! relations are supposed to be created and named on
! delivery of the option. The number of relations are
! default 4.
! Configures the server process for historical data storage.
!
! DsHistServer is configured in the development
! environment below the $Node object which represents the
! node where the Rdb storage will be done. This node will
! be referred to as the 'historical storage node'.
! In the 'historical storage node', subscriptions to
! quantities that will be included in the storage, are
! automatically set up. Data, to form an average, are
! stored in a local buffer at each storage time and an
! aritmethical average will be calculated before storage.
! Quantities which are included in the historical
! storage, but whose values are not accessible (there may
! be time-out in the subscription e.g.) will be stored as
! null characters.
! This object is used when the server is started on a node with
! the runtime environment started.
! The the server can also be started without the runtime
! environment, but with the storage environment (Sev) installed.
! See the documentation for the storage environment on how to
! start the server in this case.
!
! See Also
! DsHist,
! @b See also
! @classlink DsHistThread pwrb_dshistthread.html
! @classlink DsHistMonitor pwrb_dshistmonitor.html
! @classlink DsHist pwrb_dshist.html
!*/
Object DsHistServer $ClassDef 107
Object DsHistServer $ClassDef 535
Body SysBody
Attr Editor = pwr_eEditor_AttrEd
Attr Method = pwr_eMethod_Standard
......@@ -57,82 +47,14 @@ SObject pwrb:Class
Body SysBody
Attr StructName = "DsHistServer"
EndBody
Object Description $Attribute 1
Body SysBody
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! Specifies the name of a relation in Rdb. A relation
! consist of one row to each storage time with up to 1500
! data columns.
! The attribute is case sensitive i.e. if the relation is
! named HistoricRelation_1 it has to be written
! HistoricRelation_1 and not historicrelation_1,for
! example.
!*/
Object Table $Attribute 2
Body SysBody
Attr TypeRef = "pwrs:Type-$String40"
EndBody
EndObject
!/**
! Specifies, in seconds, the time between two storages in
! the relation. The attribute has to be an integer
! multiple of ScanTime; se below.
!*/
Object StoreInterval $Attribute 3
Body SysBody
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Specifies, in seconds, the time between two samples.
! The minimum allowed value is 10 seconds.
!
! If StoreInterval = ScanTime latest sample will be
! stored.
! If StoreInterval > ScanTime storage according to
! FilterFunction will be done.
! Optional description.
!*/
Object ScanTime $Attribute 4
Body SysBody
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Specifies, in days, how long data will be saved in Rdb.
! Rdb is on delivery created to hold a certain number of
! samples of the data quantities. The following
! expression will be satisfied,
!
! StoreTime <= "maximum number of samples" * StoreInterval
!*/
Object StoreTime $Attribute 5
Body SysBody
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Specifies how a sample will be handled before storage.
! The following alternatives exist:
! -- At storage the latest sample of the quantity will
! -- At storage the arithmetical average of the quantity
! will be used.
!*/
Object FilterFunction $Attribute 6
Object Description $Attribute 1
Body SysBody
Attr TypeRef = "pwrs:Type-$UInt16"
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
EndObject
Object Template DsHistServer
Body RtBody
Attr ScanTime = 10
Attr StoreInterval = 10
Attr StoreTime = 2
Attr FilterFunction = 0
EndBody
EndObject
EndObject
EndSObject
!
! Proview $Id: pwrb_c_dshistthread.wb_load,v 1.1 2008-07-17 11:37:57 claes Exp $
! Copyright (C) 2005 SSAB Oxelsund AB.
!
! This program is free software; you can redistribute it and/or
! modify it under the terms of the GNU General Public License as
! published by the Free Software Foundation, either version 2 of
! the License, or (at your option) any later version.
!
! This program is distributed in the hope that it will be useful
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with the program, if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
!
! pwrb_c_dshistthread.wb_load -- Defines the class DsHistThread.
!
SObject pwrb:Class
!/**
! @Version 1.0
! @Group Servers,NodeConfiguration
! Configures a thread in the DsHist monitor process, with a
! specific scantime and database server node.
!
! The DsHist monitor process keeps track of all DsHist objects
! in the current node. The process is divided into threads that
! collect data with a specific scantime and sends to the specified
! database server. The threads are specified by DsHistThread objects
! that reside under the DsHistMonitor object in the node hierarchy.
!
! @b See also
! @classlink DsHist pwrb_dshist.html
! @classlink DsHistMonitor pwrb_dshistmonitor.html
! @classlink DsHistServer pwrb_dshistserver.html
!*/
Object DsHistThread $ClassDef 107
Body SysBody
Attr Editor = pwr_eEditor_AttrEd
Attr Method = pwr_eMethod_Standard
EndBody
Object RtBody $ObjBodyDef 1
Body SysBody
Attr StructName = "DsHistThread"
EndBody
!/**
! Optional description.
!*/
Object Description $Attribute 1
Body SysBody
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! The name of the node where the data is stored.
! The DsHistServer has to be started on this node.
!*/
Object ServerNode $Attribute 2
Body SysBody
Attr TypeRef = "pwrs:Type-$String40"
EndBody
EndObject
!/**
! Specifies, in seconds, the time between two samples.
! The minimum allowed value is 1 seconds.
!*/
Object ScanTime $Attribute 3
Body SysBody
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
EndObject
Object Template DsHistThread
Body RtBody
Attr ScanTime = 10
EndBody
EndObject
EndObject
EndSObject
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