示例#1
0
/*
功能:改变所有设备的power state
参数:
      newState     设备将要达到的power state
	  context      函数体中木有用到。。。。。?????
返回:0   __flase    失败
      1   __true     成功
*/
static __bool PMC_API _power_callback(int newState, int context)
{
	PDEVICE_INFO dev;
	DEVICE_LIST::iterator it;
	PDRIVER_INFO drv;
	IOSS_STATUS code;
    
	//遍历设备列表中的所有设备
	for(it = g_Devices.begin(); it != g_Devices.end(); it++){
		dev = it->second;//设备信息
		drv = dev->d;//驱动信息
		
		//调用驱动dll导出函数改变power state
		if( (dev->flags & DF_Active) && (drv->dispatch)){
			code = drv->dispatch(dev, DISP_POWER_STATE_CHANGED, newState);
			if(code){
				utils_error(
					"Error : device %s vetoed `power-state-changed' command,"
					"error code 0x%08x.\n"
					"This may cause unpredictable result.\n",
					(char*)CDeviceName(dev->k),
					code
					);
				return __false;
			}
		}
	}

	return __true;
}
示例#2
0
/*
	caller must have DB locked exclusively
*/
IO_API __bool PMC_API io_start_device(PDEVICE_INFO dev)
{
	__bool r;	

	// a fake driver is created even if the module cannot be loaded
	assert(dev->d);
	
	if(!(dev->d->flags & DRIVER_FLAG_LOADED)){
		dev->error = IOSS_DRIVER_NOT_LOADED;
		r = __false;
	}else{
		if(!dev->d->start_device){
			r = __true;
		}else{
			r = dev->d->start_device(dev);
			if(!r){
				dev->error = IOSS_DEVICE_NOT_STARTED;
			}
		}
	}
	
	if(!r){
		dev->flags &= ~DF_Active;
	}else{
		dev->flags |= DF_Active;
		dev->error = 0;
	}
	
	if(r){
		utils_trace(
			"Device %s started.\n", 
			(char*)CDeviceName(dev->k)
			);
	}else{
		utils_error(
			"Cannot start device %s.\n", 
			(char*)CDeviceName(dev->k)
			);
	}
	
	return r;
}
示例#3
0
/*
	caller must have DB locked exclusively.
*/
IO_API __bool PMC_API io_stop_device(PDEVICE_INFO dev)
{	
	if( !(dev->flags & DF_Active) ){
		return __true;
	}
	utils_trace("Stopping device %s\n", (char*)CDeviceName(dev->k));
	// newly created devices might not be attached to driver yet
	if(dev->d){
		if(dev->d->stop_device){
			if(!dev->d->stop_device(dev)){
				dev->flags &= ~DF_Active;
				utils_error(
					"Device %s not responding to STOP command.\n", 
					(char*)CDeviceName(dev->k)
					);
				return __false;
			}
		}
	}
	dev->flags &= ~DF_Active;
	utils_trace("Device %s stopped\n", (char*)CDeviceName(dev->k));
	
	return __true;
}
static void _cdecl _OnAddDevice(PCNODE_KEY n, PDEVICE_INFO di)
{
    AnsiString Url;
    Url = ToUrl(n) + ".DEVICES";
    CDeviceItems * ditems;
    ditems = dynamic_cast<CDeviceItems*>(g_DCS.Search(Url));
    if(!ditems){
        return;
    }
    CDeviceItem * ditem;
    Url = (char*)CDeviceName(di->k);
    ditem = dynamic_cast<CDeviceItem*>(ditems->Search(Url));
    if(ditem){
        ditem->info = *di;
    }else{
        ditem = new CDeviceItem(n, di);
        if(ditem){
            ditems->AddChild(ditem);
        }
    }
}
CDeviceItem::CDeviceItem(PCNODE_KEY node, DEVICE_INFO *di)
{
    this->node = *node;
    info = *di;
    m_bExpandable = false;
    if(info.flags & DF_Deleted){
        m_iIcon = 26;
    }else{
        if(info.flags & DF_Active){
            m_iIcon = 27;
        }else{
            m_iIcon = 28;
        }
    }
    m_sCaption = (char*)CDeviceName(info.k);
    m_ClassName = "IO 设备";
    m_SearchKey = m_sCaption;
    m_PropertyPage = framDeviceView;
    m_AddPage = framAddDevice;
    m_SupportedActions.insert(ca_Add);
    m_SupportedActions.insert(ca_Edit);
    m_SupportedActions.insert(ca_Delete);
    active = false;
}
/*
	Load data from storage to UI
*/
void __fastcall TframTag::UpdateView()
{
	//TODO: Add your source code here
	TComponent * comp;
	int i;
	PTAG_NAME name = &m_TagName;
	// update static information
	PRTK_TAG pTag = &m_Tag;
	char textname[TAGNAME_TEXT_LENGTH + 1];
	char buf[64];

	// temporarily disable unapplicable components
	tsException->TabVisible = false;
    
    btnWriteDevice->Enabled = (pTag->d.Value.Flags & TF_ReadOnly)? false : true;

	// now we update the UI to reflect the tag configuration
    /*
    0 开关量
    1 模拟量
    2 高精度模拟量
    3 8位整数
    4 16位整数
    5 32位整数
    6 64位整数
    7 无符号8位整数
    8 无符号16位整数
    9 无符号32位整数
    10 无符号64位整数
    11 日期
    */
	cmbType->OnChange = NULL;
	switch(get_value_type(pTag->s.Flags)){
	case dt_bool:
		cmbType->ItemIndex = 0;
		break;
	case dt_real4:
    	cmbType->ItemIndex = 1;
	    break;
	case dt_real8:
		cmbType->ItemIndex = 2;
		break;
    case dt_int8:
        cmbType->ItemIndex = 3;
        break;
    case dt_int16:
        cmbType->ItemIndex = 4;
        break;
    case dt_int32:
        cmbType->ItemIndex = 5;
        break;
    case dt_int64:
        cmbType->ItemIndex = 6;
        break;
    case dt_uint8:
        cmbType->ItemIndex = 7;
        break;
    case dt_uint16:
        cmbType->ItemIndex = 8;
        break;
    case dt_uint32:
        cmbType->ItemIndex = 9;
        break;
    case dt_uint64:
        cmbType->ItemIndex = 10;
        break;
	case dt_date:
    	cmbType->ItemIndex = 11;
    	break;
    default:
    	cmbType->ItemIndex = 12;
    	break;
	}
	cmbType->OnChange = cmbTypeChange;

	{
		cmbDevice->Ctl3D = false;
		CDeviceItems * ditems;
		AnsiString Url;
		Url = (char*)CNodeName(name->node);
		Url += ".DEVICES";
		ditems = dynamic_cast<CDeviceItems*>(g_DCS.Search(Url));
		if(ditems){
			if(!ditems->m_iRefreshCount){
				ditems->Refresh();
			}
		}
		cmbDevice->Items->Clear();
		cmbDevice->Text = "";
		if(ditems){
			CDeviceItem * ditem;
			ditem = dynamic_cast<CDeviceItem*>(ditems->GetFirstChild());
			while(ditem){
				cmbDevice->Items->Add((char*)CDeviceName(ditem->info.k));
				ditem = dynamic_cast<CDeviceItem*>(ditems->GetNextChild(ditem));
			}
		}
	}

	{
		PRTK_GROUP pgrp;
		RTK_CURSOR hgrp;
		hgrp = open_group_f(&name->node, &name->sname.group);
		pgrp = (PRTK_GROUP)cursor_get_item(hgrp);
		if(pgrp){
			if(pgrp->period > 50){
				tmrUpdater->Interval = pgrp->period;
			}
		}
		close_handle(hgrp);
	}

	edtTagName->Text = (char *)CTagName(name->sname.tag);
	edtCName->Text = pTag->s.Description;
	edtAddr->Text  = pTag->s.Address;
	cmbDevice->Text = (char*)CDeviceName(pTag->s.Device);
#define cc(name) \
	do{ if(pTag->s.Flags & TF_##name){\
			chk##name->Checked =  true;\
		}else{\
			chk##name->Checked = false;\
		}\
	}while(0)
	cc(HiHi);
	cc(Lo);
	cc(Hi);
	cc(LoLo);
	cc(On2Off);
	cc(Off2On);
	cc(Rate);
	cc(SaveToHistory);
    cc(Step);
/*
	// cutoff is obsolete
#define dd(name) chk##name->Checked = pTag->s.CutOffMask & TF_##name ? true : false;
	dd(HiHi);
	dd(Lo);
	dd(Hi);
	dd(LoLo);
	dd(On2Off);
	dd(Off2On);
*/
	if(pTag->s.Flags & TF_System){
		cmbDevice->Enabled = false;
		edtAddr->ReadOnly = true;
		cmbType->Enabled = false;
		cmbDevice->Color = clScrollBar;
		edtAddr->Color = clScrollBar;
		cmbType->Color = clScrollBar;
	}else{
		cmbDevice->Enabled = true;
		edtAddr->ReadOnly = false;
		cmbType->Enabled = true;
		cmbType->Color = clWindow;

		cmbDevice->Color = clWindow;
		edtAddr->Color = clWindow;
	}
	
	switch(get_value_type(pTag->s.Flags)){
	case dt_real4:
	case dt_real8:
    case dt_int64:
    case dt_uint64:
		#define aa(f) sprintf(buf, "%g", pTag->s.flt##f);edt##f->Text = buf;
		aa(HiHi);
		aa(Hi);
		aa(Lo);
		aa(LoLo);
		aa(AlarmDeadband);
		aa(MaxValue);
		aa(MinValue);
		aa(Rate);
		edtEU->Text = pTag->s.AnalogMsg.EU;
		tsAnalog->TabVisible = true;
		tsLogical->TabVisible = false;
		break;
	case dt_int8:
    case dt_int16:
	case dt_int32:
    case dt_uint8:
	case dt_uint16:
    case dt_uint32:
		aa(AlarmDeadband);
		aa(Rate);
		#undef aa
		#define aa(v, name) \
			sprintf(buf, "%d", pTag->s.v);\
			edt##name->Text = buf;
		aa(u_hihi.i, HiHi);
		aa(u_hi.i, Hi);
		aa(u_lo.i, Lo);
		aa(u_lolo.i, LoLo);
		aa(u_max.i, MaxValue);
		aa(u_min.i, MinValue);
		edtEU->Text   = pTag->s.AnalogMsg.EU;
		tsAnalog->TabVisible = true;
		tsLogical->TabVisible = false;
		break;
	case dt_date:
		tsArchive->TabVisible = true;
		tsAnalog->TabVisible = false;
		tsLogical->TabVisible = false;
		break;
	case dt_bool:
		edtOnMessage->Text = pTag->s.SwitchMsg.OnMsg;
		edtOffMessage->Text = pTag->s.SwitchMsg.OffMsg;
		tsLogical->TabVisible = true;
		tsAnalog->TabVisible = false;		
	default:
		assert(0);
		break;
	}

	tsAnalog->Visible = tsAnalog->TabVisible;
	tsLogical->Visible = tsLogical->TabVisible;
	tsException->Visible = tsException->TabVisible;
	tsArchive->Visible = tsArchive->TabVisible;
	
	edtAlarmRank->Text = pTag->s.AlarmRank;
    edtAlarmRank2->Text = pTag->s.AlarmRank;

	chkCompressing->Checked = true;
	edtCompMax->Enabled = chkCompressing->Checked;
	edtCompDev->Enabled = chkCompressing->Checked;
	edtCompDevPercent->Enabled = chkCompressing->Checked;
	edtCompMax->Text = IntToStr(pTag->s.CompMax);
	edtCompDev->Text = FloatToStr(pTag->s.CompDev);
    __r8 span = _getSpan(pTag);
    if(span > 1e-5){
		edtCompDevPercent->Text = FloatToStr(pTag->s.CompDev / span * 100);
    }

	TAG_NAME ctn;
	ZeroMemory(&ctn, sizeof(ctn));
	ctn.sname = pTag->s.CutOffTagName;
	tagname_to_text(&ctn, textname, sizeof(textname));
	
	// debugging output
	{
		char nn[128];
		*nn=0;
	#define __check_field__(field,name) \
		if(pTag->d.Value.Flags & TF_##field) {\
			if(*nn) {\
				strcat(nn,"+");\
				strcat(nn,#name);\
			}else{\
				strcpy(nn,#name);\
			}\
		}
		__check_field__(HiHi,h2)
		__check_field__(Hi,h)
		__check_field__(LoLo,l2)
		__check_field__(Lo,l)
		__check_field__(Rate,r)
		__check_field__(On2Off,off)
		__check_field__(Off2On,on)
		__check_field__(Alarm,alarm)
		__check_field__(Expired,expired)
		__check_field__(SharpChange,sharp)
		__check_field__(ReadOnly,read)
		__check_field__(Translated,trans)
		__check_field__(ConfigOk,ok)
		__check_field__(Valid,valid)
		utils_debug("%s flags=0x%08x,%s\n", textname, pTag->d.Value.Flags, nn);
	#undef __check_field__
	}

	// pg->Clear();
}
/*
	gather data from UI to internal representation
*/
bool TframTag::ValidateView()
{
	PTAG_NAME name;
	PRTK_TAG tag;	
	name = &m_TagName;
	tag = &m_Tag;
	
	try{
	#undef cc

	#define cc(name) tag->s.Flags |= (chk##name->Checked ? TF_##name : 0);

		if( edtTagName->Text.Length() >sizeof(TAG_KEY) ||
			!edtTagName->Text.Length()
		){
			m_Hint = "变量名不正确";
			throw(-1);
		}
		if( !is_valid_name(edtTagName->Text.c_str()) ){
			m_Hint = "变量名只能包含字母、数字和下划线";
			throw(-3);
		}
		if(edtTagName->Text.Length() > sizeof(TAG_KEY)){		
			m_Hint = AnsiString("错误: 标签名不能超过 ") + IntToStr(sizeof(TAG_KEY)) + " 个字节";		 
			throw(-3);
		}
		name->sname.tag = CTagName(edtTagName->Text.c_str());
		tag->s.Device = CDeviceName(cmbDevice->Text.c_str());
		tag->key = name->sname.tag;
		if(edtCName->Text.Length() > sizeof(tag->s.Description)){
			m_Hint = "中文名太长(最长 " + AnsiString(sizeof(tag->s.Description)/2) + " 字)";
			throw(-4);
		}
		strncpy(tag->s.Description, edtCName->Text.c_str(), sizeof(tag->s.Description));
		tag->s.Description[sizeof(tag->s.Description) - 1] = 0;
		if(edtAddr->Text.Length() > sizeof(tag->s.Address)){
			m_Hint = "地址太长(最长 " + AnsiString(sizeof(tag->s.Address)/2) + " 字)";
			throw(-5);
		}
		strncpy(tag->s.Address, edtAddr->Text.c_str(), sizeof(tag->s.Address));
		tag->s.Address[sizeof(tag->s.Address) - 1] = 0;

        tag->s.Flags = 0;
        
		switch(cmbType->ItemIndex){
		case 0:
			set_value_type(tag->s.Flags, dt_bool);
			break;
		case 1:
			set_value_type(tag->s.Flags, dt_real4);
			break;
		case 2:
			set_value_type(tag->s.Flags, dt_real8);
			break;

		case 3:
			set_value_type(tag->s.Flags, dt_int8);
			break;
		case 4:
			set_value_type(tag->s.Flags, dt_int16);
			break;
		case 5:
			set_value_type(tag->s.Flags, dt_int32);
			break;
		case 6:
			set_value_type(tag->s.Flags, dt_int64);
			break;

		case 7:
			set_value_type(tag->s.Flags, dt_uint8);
			break;
		case 8:
			set_value_type(tag->s.Flags, dt_uint16);
			break;
		case 9:
			set_value_type(tag->s.Flags, dt_uint32);
			break;
		case 10:
			set_value_type(tag->s.Flags, dt_uint64);
			break;

        case 11:
            set_value_type(tag->s.Flags, dt_date);
            break;

        case 12:
            m_Hint = "不支持这个数据类型.";
            throw(-41);
            break;
		}

		cc(SaveToHistory);
        cc(Step);

		// collecting common analog attributes
		switch(get_value_type(tag->s.Flags)){
        case dt_int8:
		case dt_int16:
		case dt_int32:
        case dt_int64:
        case dt_uint8:
		case dt_uint16:
		case dt_uint32:
        case dt_uint64:
        case dt_real4:
		case dt_real8:
        case dt_date:
			cc(HiHi);
			cc(Lo);
			cc(Hi);
			cc(LoLo);
			cc(Rate);
			strncpy(
				tag->s.AnalogMsg.EU,
				edtEU->Text.c_str(),
				sizeof(tag->s.AnalogMsg.EU)
				);
			tag->s.AnalogMsg.EU[sizeof(tag->s.AnalogMsg.EU) - 1] = 0;
			break;
		case dt_bool:
			cc(On2Off);
			cc(Off2On);
			
			strncpy(
				tag->s.SwitchMsg.OnMsg,
				edtOnMessage->Text.c_str(),
				sizeof(tag->s.SwitchMsg.OnMsg)
				);
			tag->s.SwitchMsg.OnMsg[sizeof(tag->s.SwitchMsg.OnMsg) - 1] = 0;
			strncpy(
				tag->s.SwitchMsg.OffMsg,
				edtOffMessage->Text.c_str(),
				sizeof(tag->s.SwitchMsg.OffMsg)
				);
			tag->s.SwitchMsg.OffMsg[sizeof(tag->s.SwitchMsg.OffMsg) - 1] = 0;
			break;
		}

#define get(msg, name, ignore_on_condition, _default_value)\
	m_Hint = msg;\
	if( !edt##name->Text.Length() ){\
		if(ignore_on_condition){\
			tag->s.flt##name = _default_value;\
		}else{\
			throw(-1);\
		}\
	}else{\
		tag->s.flt##name = edt##name->Text.ToDouble();\
	}
#pragma warn -ccc
#pragma warn -rch
		switch(get_value_type(tag->s.Flags)){
		case dt_real4:
		case dt_real8:
			get("高高值不正确", HiHi, !chkHiHi->Checked, 0);
			get("低低值不正确", LoLo, !chkLoLo->Checked, 0);
			get("低值不正确", Lo, !chkLo->Checked, 0);
			get("高值不正确", Hi, !chkHi->Checked, 0);
			get("报警死区值不正确", AlarmDeadband, !(tag->s.Flags & 0xffffff00), 0);
			get("最大值不正确", MaxValue, false, 0);
			get("最小值不正确", MinValue, false, 0);
			get("速率报警阈值不正确", Rate, !chkRate->Checked, 0.1);
			break;

		case dt_int8:
		case dt_int16:
		case dt_int32:
        case dt_int64:
		case dt_uint8:
		case dt_uint16:
		case dt_uint32:
        case dt_uint64:
			get("速率报警阈值不正确", Rate, !chkRate->Checked, 0.1);
#undef get
#define get(msg, attrName, uiName, ignore_on_condition, _default_value)\
	m_Hint = msg;\
	if( !edt##uiName->Text.Length() ){\
		if(ignore_on_condition){\
			tag->s.##attrName = _default_value;\
		}else{\
			throw(-1);\
		}\
	}else{\
		tag->s.attrName = edt##uiName->Text.ToDouble();\
	}
			get("高高值不正确", u_hihi.i, HiHi, !chkHiHi->Checked, 0);
			get("低低值不正确", u_lolo.i, LoLo, !chkLoLo->Checked, 0);
			get("低值不正确", u_lo.i, Lo, !chkLo->Checked, 0);
			get("高值不正确", u_hi.i, Hi, !chkHi->Checked, 0);
			get("报警死区值不正确", u_deadband.i, AlarmDeadband, !(tag->s.Flags & 0xffffff00), 0);
			get("最大值不正确", u_max.i, MaxValue, false, 0);
			get("最小值不正确", u_min.i, MinValue, false, 0);
			break;
		}

#pragma warn .ccc
#pragma warn .rch

        if(get_value_type(tag->s.Flags) == dt_bool){
            tag->s.AlarmRank = edtAlarmRank2->Text.ToInt();
        }else{
    		tag->s.AlarmRank = edtAlarmRank->Text.ToInt();
        }

		tag->s.Compressing = Compress_Const;
		tag->s.CompDev = StrToFloat(edtCompDev->Text);
		tag->s.CompMax = StrToInt(edtCompMax->Text);
	}catch(...){
		return false;
	}
	m_Hint = "更新成功";
	return true;
}