Example #1
0
/** Checks for climate object and maps the climate variables to the house object variables.  
Currently Tout, RHout and solar flux data from TMY files are used.  If no climate object is linked,
then Tout will be set to 74 degF, RHout is set to 75% and solar flux will be set to zero for all orientations.
**/
int house::init_climate()
{
	OBJECT *hdr = OBJECTHDR(this);

	// link to climate data
	static FINDLIST *climates = NULL;
	int not_found = 0;
	if (climates==NULL && not_found==0) 
	{
		climates = gl_find_objects(FL_NEW,FT_CLASS,SAME,"climate",FT_END);
		if (climates==NULL)
		{
			not_found = 1;
			gl_warning("house: no climate data found, using static data");

			//default to mock data
			static double tout=74.0, rhout=0.75, solar[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
			pTout = &tout;
			pRhout = &rhout;
			pSolar = &solar[0];
		}
		else if (climates->hit_count>1)
		{
			gl_warning("house: %d climates found, using first one defined", climates->hit_count);
		}
	}
	if (climates!=NULL)
	{
		if (climates->hit_count==0)
		{
			//default to mock data
			static double tout=74.0, rhout=0.75, solar[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
			pTout = &tout;
			pRhout = &rhout;
			pSolar = &solar[0];
		}
		else //climate data was found
		{
			// force rank of object w.r.t climate
			OBJECT *obj = gl_find_next(climates,NULL);
			if (obj->rank<=hdr->rank)
				gl_set_dependent(obj,hdr);
			pTout = (double*)GETADDR(obj,gl_get_property(obj,"temperature"));
			pRhout = (double*)GETADDR(obj,gl_get_property(obj,"humidity"));
			pSolar = (double*)GETADDR(obj,gl_get_property(obj,"solar_flux"));
		}
	}
	return 1;
}
double *transmissioncom::get_double(OBJECT *obj, char *name)
{
	PROPERTY *p = gl_get_property(obj,name);
	if (p==NULL || p->ptype!=PT_double)
		return NULL;
	return (double*)GETADDR(obj,p);
}
Example #3
0
complex *microturbine::get_complex(OBJECT *obj, char *name)
{
	PROPERTY *p = gl_get_property(obj,name);
	if (p==NULL || p->ptype!=PT_complex)
		return NULL;
	return (complex*)GETADDR(obj,p);
}
Example #4
0
//Retrieve the address of a metric
double *metrics::get_metric(OBJECT *obj, char *name)
{
	PROPERTY *p = gl_get_property(obj,name);
	if (p==NULL || p->ptype!=PT_double)
		return NULL;
	return (double*)GETADDR(obj,p);
}
Example #5
0
//Function to extract address of outage flag
bool *metrics::get_outage_flag(OBJECT *obj, char *name)
{
	PROPERTY *p = gl_get_property(obj,name);
	if (p==NULL || p->ptype!=PT_bool)
		return NULL;
	return (bool*)GETADDR(obj,p);
}
bool *inverter::get_bool(OBJECT *obj, char *name)
{
	PROPERTY *p = gl_get_property(obj,name);
	if (p==NULL || p->ptype!=PT_bool)
		return NULL;
	return (bool*)GETADDR(obj,p);
}
/** Water heater synchronization determines the time to next
	synchronization state and the power drawn since last synch
 **/
TIMESTAMP virtual_battery::sync(TIMESTAMP t0, TIMESTAMP t1) 
{
	TIMESTAMP t2 = TS_NEVER;
	//printf("sync: %f ",capacity);
	double 	*pSolarD = (double*)GETADDR(climate_object,gl_get_property(climate_object,"solar_flux"));
		
	
	if(first_time==2 && first_time2==0)
	{	
		if(ch==1)
		{
					//system("pause");
					if(capacity >= 100000 )
					{

					//	printf("sync 1:%f	\n",capacity);
					 //   system("pause");
						charge=0;
	
					}
					if(capacity < max_capacity *0.2)
					{
	
		
					//	printf("sync 2:%f	\n",capacity);
					//	system("pause");
						charge=1;
					}


					//if(*pSolarD > 0)
					//{
							if(charge==1 )
							{
		
		    					//system("pause");
								capacity=capacity + (*power)/drilling_systems;
							//	printf("sync 3:%f	\n",capacity);
						//	system("pause");
		
							}
					//}
							//printf("%f\n\n", capacity);
		}
	ch=0;
	}
		
	return TS_NEVER;
}
int WiFiEngine_RegisterMIBTable(const void *table, size_t size, uint32_t vaddr)
{
   struct mib_table *tmp;
   mib_object_reference_type_t type;
   mib_object_size_description_t sdesc;
   uint32_t addr;
   uint32_t esize;

   tmp = DriverEnvironment_Malloc(sizeof(*tmp) - sizeof(tmp->table) + size);
   if(tmp == NULL) {
      DE_TRACE_STATIC(TR_ALWAYS, "failed to allocate memory for MIB table\n");
      return WIFI_ENGINE_FAILURE_RESOURCES;
   }
   DE_MEMCPY(tmp->table, table, size);
   tmp->size = size;
   tmp->vaddr = vaddr;

   type = (mib_object_reference_type_t)GETFIELD(tmp->table[0].storage_description, REFERENCE_TYPE);
   sdesc = (mib_object_size_description_t)GETFIELD(tmp->table[0].storage_description, OBJECT_SIZE_DESCRIPTION);
   addr = GETADDR(tmp->table[0].reference);
   esize = GETFIELD(tmp->table[0].storage_description, OBJECT_SIZE);
   if(type != MIB_OBJECT_REFERENCE_TYPE_MIB_TABLE
      || sdesc != MIB_OBJECT_SIZE_DESCRIPTION_FIXED_SIZE
      || !ADDRVALID(addr, tmp)) {
      DE_TRACE_INT5(TR_ALWAYS, "bad MIB table format t:%x s:%x a:%x e:%x v:%x\n",
            type, sdesc, addr, esize, ADDRVALID(addr, tmp));
      DriverEnvironment_Free(tmp);
      return WIFI_ENGINE_FAILURE_INVALID_DATA;
   }
   tmp->rootindex = ADDRTOINDEX(addr, tmp);
   tmp->rootentries = esize;

   wei_free_mibtable();

   mibtable = tmp;

   return WIFI_ENGINE_SUCCESS;
}
/**
	@return 0 on failure, 1 on success
 **/
int group_recorder::read_line(){
	size_t index = 0, offset = 0, unit_len = 0;
	quickobjlist *curr = 0;
	char *swap_ptr = 0;
	char buffer[128];
	char objname[128];

	if(TS_OPEN != tape_status){
		// could be ERROR or CLOSED
		return 0;
	}

	// pre-calculate buffer needs
	if(line_size <= 0 || line_buffer == 0){
		size_t prop_size;
		
		// in v2.3, there's no measure of the property's string representation size.
		//	this value *is* present in 3.0.
		prop_size = 48;

		line_size = (prop_size + 1) * obj_count + 1;
		line_buffer = (char *)malloc(line_size);
		if(0 == line_buffer){
			return 0;
		}
		memset(line_buffer, 0, line_size);
		if(-1 == write_interval){ // 'on change', will need second buffer
			prev_line_buffer = (char *)malloc(line_size);
			if(0 == prev_line_buffer){
				gl_error("group_recorder::read_line(): malloc failure");
				/* TROUBLESHOOT
					Memory allocation failure.
				*/
				return 0;
			}
			memset(prev_line_buffer, 0, line_size);
		}
	}

	// if we need the previous buffer to compare against, swap the buffers
	if(-1 == write_interval){
		swap_ptr = prev_line_buffer;
		prev_line_buffer = line_buffer;
		line_buffer = swap_ptr;
	}
	memset(line_buffer, 0, line_size);
	for(curr = obj_list; curr != 0; curr = curr->next){
		// GETADDR is a macro defined in object.h
		if(curr->prop->ptype == PT_complex && complex_part != NONE){
			double part_value = 0.0;
			complex *cptr = 0;
			// get value as a complex
			cptr = gl_get_complex(curr->obj, curr->prop);
			if(0 == cptr){
				gl_error("group_recorder::read_line(): unable to get complex property '%s' from object '%s'", curr->prop->name, gl_name(curr->obj, objname, 127));
				/* TROUBLESHOOT
					Could not read a complex property as a complex value.
				 */
				return 0;
			}
			// switch on part
			switch(complex_part){
				case NONE:
					// didn't we test != NONE just a few lines ago?
					gl_error("group_recorder::read_line(): inconsistant complex_part states!");
					return 0;
				case REAL:
					part_value = cptr->Re();
					break;
				case IMAG:
					part_value = cptr->Im();
					break;
				case MAG:
					part_value = cptr->Mag();
					break;
				case ANG:
					part_value = cptr->Arg() * 180/PI;
					break;
				case ANG_RAD:
					part_value = cptr->Arg();
					break;
			}
			sprintf(buffer, "%f", part_value);
			offset = strlen(buffer);
		} else {
			offset = gl_get_value(curr->obj, GETADDR(curr->obj, curr->prop), buffer, 127, prop_ptr);
			if(0 == offset){
				gl_error("group_recorder::read_line(): unable to get value for '%s' in object '%s'", curr->prop->name, curr->obj->name);
				/* TROUBLESHOOT
					An error occured while reading the specified property in one of the objects.
				 */
				return 0;
			}
		}
		// check line_buffer space
		unit_len = ((print_units && 0 != curr->prop && 0 != curr->prop->unit) ? 1 + strlen(curr->prop->unit->name) : 0);
		if( unit_len + (index + offset + 1) > line_size ){
			gl_error("group_recorder::read_line(): potential buffer overflow from a too-short automatically sized output value buffer");
			/* TROUBLESHOOT
				A potential buffer overflow was caught, most likely due to incorrect property
				representation assumptions for buffer allocation.
			 */
			return 0;
		}
		// write to line_buffer
		// * lead with a comma on all entries, assume leading timestamp will NOT print a comma
		if(print_units && 0 != curr->prop && 0 != curr->prop->unit){
			if(0 >= sprintf(line_buffer+index, ",%s %s", buffer, curr->prop->unit->name)){return 0;}
		} else {
			if(0 >= sprintf(line_buffer+index, ",%s", buffer)){return 0;}
		}
		index += (offset + 1) + unit_len; // add the comma
	}
	// assume write_line will add newline character

	return 1;
}
Example #10
0
void
wifi_pcap_callback(u_char* av, const struct pcap_pkthdr * pkthdr, const u_char * pkt)
{
  ieee80211_header_t mac_header;
  prism2_header_t prism2_header;
  u_int8_t dir, type, subtype;
  ovm_var_t **attr;

  DebugLog(DF_MOD, DS_TRACE, "wifi_pcap_callback()\n");

  attr = (ovm_var_t **) av;

  if (datalink_type == DLT_PRISM_HEADER) {
    prism2_header = (prism2_header_t) pkt;
    mac_header = (ieee80211_header_t) (pkt + 144);

    attr[F_RSSI] = ovm_int_new();
    INT(attr[F_RSSI]) = (&(prism2_header->rssi))->data;
  } else {
      return ;
  }

  /* fixation du champ .wifi.time */
  attr[F_TIME] = ovm_timeval_new();
  attr[F_TIME]->flags |= TYPE_MONO;
  gettimeofday( &(TIMEVAL(attr[F_TIME])) , NULL);

  type = mac_header->fc[0] & 0x0c;
  subtype = mac_header->fc[0] & SUBTYPE_MASK;
  dir = mac_header->fc[1] & DIR_MASK;

  switch (type) {
    /******************** Dans le cas d'une trame de gestion */
    case TYPE_MGT:

      attr[F_TYPE] = ovm_str_new(strlen("management"));
      memcpy(STR(attr[F_TYPE]), "management", STRLEN(attr[F_TYPE]));

      /* fixation du champ .wifi.seqnum */
      attr[F_SEQNUM] = ovm_int_new();
      INT(attr[F_SEQNUM]) = (int) (mac_header->seqnum & SEQ_MASK) \
                               >> SEQ_SHIFT;

      /* addr1 = DA
         addr2 = SA
         addr3 = BSSID */

      GETADDR(mac_header->addr1, attr[F_DA]);
      GETADDR(mac_header->addr2, attr[F_SA]);
      GETADDR(mac_header->addr3, attr[F_BSSID]);

      switch(subtype)
      {
        case SUBTYPE_ASSOC_REQ:
          attr[F_SUBTYPE] = ovm_str_new(strlen("assocreq"));
          memcpy(STR(attr[F_SUBTYPE]), "assocreq", STRLEN(attr[F_SUBTYPE]));
          break;

        case SUBTYPE_ASSOC_RESP:
          attr[F_SUBTYPE] = ovm_str_new(strlen("assocresp"));
          memcpy(STR(attr[F_SUBTYPE]), "assocresp", STRLEN(attr[F_SUBTYPE]));
          break;

        case SUBTYPE_PROBE_REQ:
          attr[F_SUBTYPE] = ovm_str_new(strlen("probereq"));
          memcpy(STR(attr[F_SUBTYPE]), "probereq", STRLEN(attr[F_SUBTYPE]));
          break;

        case SUBTYPE_PROBE_RESP:
          attr[F_SUBTYPE] = ovm_str_new(strlen("proberesp"));
          memcpy(STR(attr[F_SUBTYPE]), "proberesp", STRLEN(attr[F_SUBTYPE]));
          break;

        case SUBTYPE_BEACON:
          attr[F_SUBTYPE] = ovm_str_new(strlen("beacon"));
          memcpy(STR(attr[F_SUBTYPE]), "beacon", STRLEN(attr[F_SUBTYPE]));
          break;

        case SUBTYPE_DISASSOC:
          attr[F_SUBTYPE] = ovm_str_new(strlen("disassoc"));
          memcpy(STR(attr[F_SUBTYPE]), "disassoc", STRLEN(attr[F_SUBTYPE]));
          break;

        case SUBTYPE_AUTH:
          attr[F_SUBTYPE] = ovm_str_new(strlen("auth"));
          memcpy(STR(attr[F_SUBTYPE]), "auth", STRLEN(attr[F_SUBTYPE]));
          break;

        case SUBTYPE_DEAUTH:
          attr[F_SUBTYPE] = ovm_str_new(strlen("deauth"));
          memcpy(STR(attr[F_SUBTYPE]), "deauth", STRLEN(attr[F_SUBTYPE]));
          break;

        default:
          DebugLog(DF_MOD, DS_DEBUG, "unknown_80211_mgmt_subtype_0x%.2x\n", subtype);
          attr[F_SUBTYPE] = ovm_str_new(strlen("unknown_mgmt_subtype"));
          memcpy(STR(attr[F_SUBTYPE]), "unknown_mgmt_subtype", STRLEN(attr[F_SUBTYPE]));
      }  /* end switch(subtype) */

      break;



    /******************** Dans le cas d'une trame de controle */
    case TYPE_CTL:
      attr[F_TYPE] = ovm_str_new(strlen("control"));
      memcpy(STR(attr[F_TYPE]), "control", STRLEN(attr[F_TYPE]));

      switch(subtype)
      {
        case SUBTYPE_RTS:
          attr[F_SUBTYPE] = ovm_str_new(strlen("rts"));
          memcpy(STR(attr[F_SUBTYPE]), "rts", STRLEN(attr[F_SUBTYPE]));

          GETADDR(mac_header->addr1, attr[F_RA]);
          GETADDR(mac_header->addr2, attr[F_TA]);

          break;

        case SUBTYPE_CTS:
          attr[F_SUBTYPE] = ovm_str_new(strlen("cts"));
          memcpy(STR(attr[F_SUBTYPE]), "cts", STRLEN(attr[F_SUBTYPE]));

          GETADDR(mac_header->addr1, attr[F_RA]);

          break;

        case SUBTYPE_ACK:
          attr[F_SUBTYPE] = ovm_str_new(strlen("ack"));
          memcpy(STR(attr[F_SUBTYPE]), "ack", STRLEN(attr[F_SUBTYPE]));

          GETADDR(mac_header->addr1, attr[F_RA]);

          break;

        default:
          DebugLog(DF_MOD, DS_DEBUG, "unknown_80211_ctl_subtype_0x%.2x\n", subtype);
          attr[F_SUBTYPE] = ovm_str_new(strlen("unknown_ctl_subtype"));
          memcpy(STR(attr[F_SUBTYPE]), "unknown_ctl_subtype", STRLEN(attr[F_SUBTYPE]));

      }; /* end switch(subtype) */

      break;



    /******************** Dans le cas d'une trame de donnees */
    case TYPE_DATA:

      attr[F_TYPE] = ovm_str_new(strlen("data"));
      memcpy(STR(attr[F_TYPE]), "data", STRLEN(attr[F_TYPE]));

      /* fixation du champ .wifi.iswep */
      attr[F_ISWEP] = ovm_int_new();
      INT(attr[F_ISWEP]) = (mac_header->fc[1] & PROT) / 64;

      /* fixation du champ .wifi.seqnum */
      attr[F_SEQNUM] = ovm_int_new();
      INT(attr[F_SEQNUM]) = (int) (mac_header->seqnum & SEQ_MASK) \
                               >> SEQ_SHIFT;

      switch(subtype)
      {
        case SUBTYPE_DATA:
          attr[F_SUBTYPE] = ovm_str_new(strlen("data"));
          memcpy(STR(attr[F_SUBTYPE]), "data", STRLEN(attr[F_SUBTYPE]));

          break;
        case SUBTYPE_CF_ACK:
          attr[F_SUBTYPE] = ovm_str_new(strlen("datacfack"));
          memcpy(STR(attr[F_SUBTYPE]), "datacfack", STRLEN(attr[F_SUBTYPE]));

          break;
        case SUBTYPE_CF_POLL:
          attr[F_SUBTYPE] = ovm_str_new(strlen("datacfpoll"));
          memcpy(STR(attr[F_SUBTYPE]), "datacfpoll", STRLEN(attr[F_SUBTYPE]));

          break;
        case SUBTYPE_CF_ACPL:
          attr[F_SUBTYPE] = ovm_str_new(strlen("datacfacpl"));
          memcpy(STR(attr[F_SUBTYPE]), "datacfacpl", STRLEN(attr[F_SUBTYPE]));

          break;
        case SUBTYPE_NODATA:
          attr[F_SUBTYPE] = ovm_str_new(strlen("nodata"));
          memcpy(STR(attr[F_SUBTYPE]), "nodata", STRLEN(attr[F_SUBTYPE]));

          break;

        default:
          DebugLog(DF_MOD, DS_DEBUG, "unknown_80211_data_subtype_0x%.2x\n", subtype);
          attr[F_SUBTYPE] = ovm_str_new(strlen("unknown_data_subtype"));
          memcpy(STR(attr[F_SUBTYPE]), "unknown_data_subtype", STRLEN(attr[F_SUBTYPE]));

      } /* end switch(subtype) */

      switch(dir)
      {
        case DIR_NODS:

          attr[F_DIR] = ovm_str_new(strlen("nods"));
          memcpy(STR(attr[F_DIR]), "nods", STRLEN(attr[F_DIR]));

          attr[F_BODYLENGTH] = ovm_int_new();
          INT(attr[F_BODYLENGTH]) = pkthdr->caplen - 144 - 28 ;

	  /* addr1 = DA
             addr2 = SA
             addr3 = BSSID */

          GETADDR(mac_header->addr1, attr[F_DA]);
          GETADDR(mac_header->addr2, attr[F_SA]);
          GETADDR(mac_header->addr3, attr[F_BSSID]);

          break;


        case DIR_TODS:

          attr[F_DIR] = ovm_str_new(strlen("tods"));
          memcpy(STR(attr[F_DIR]), "tods", STRLEN(attr[F_DIR]));

          attr[F_BODYLENGTH] = ovm_int_new();
          INT(attr[F_BODYLENGTH]) = pkthdr->caplen - 144 - 28 ;

	  /* addr1 = BSSID
             addr2 = SA
             addr3 = DA */

          GETADDR(mac_header->addr1, attr[F_BSSID]);
          GETADDR(mac_header->addr2, attr[F_SA]);
          GETADDR(mac_header->addr3, attr[F_DA]);

          break;


        case DIR_FROMDS:

          attr[F_DIR] = ovm_str_new(strlen("fromds"));
          memcpy(STR(attr[F_DIR]), "fromds", STRLEN(attr[F_DIR]));

          attr[F_BODYLENGTH] = ovm_int_new();
          INT(attr[F_BODYLENGTH]) = pkthdr->caplen - 144 - 28 ;

	  /* addr1 = DA
             addr2 = BSSID
             addr3 = SA */

          GETADDR(mac_header->addr1, attr[F_DA]);
          GETADDR(mac_header->addr2, attr[F_BSSID]);
          GETADDR(mac_header->addr3, attr[F_SA]);

          break;



        case DIR_DSTODS:

          attr[F_DIR] = ovm_str_new(strlen("dstods"));
          memcpy(STR(attr[F_DIR]), "fromds", STRLEN(attr[F_DIR]));

          attr[F_BODYLENGTH] = ovm_int_new();
          INT(attr[F_BODYLENGTH]) = pkthdr->caplen - 144 - 34 ;

	  /* addr1 = RA
             addr2 = TA
             addr3 = DA
             addr4 = SA */

          GETADDR(mac_header->addr1, attr[F_RA]);
          GETADDR(mac_header->addr2, attr[F_TA]);
          GETADDR(mac_header->addr3, attr[F_DA]);
          GETADDR(mac_header->addr4, attr[F_SA]);

          break;

        default: DebugLog(DF_MOD, DS_DEBUG, "unknown_80211_frame_direction_0x%.2x\n", dir);

      } /* end switch(dir) */

      break;

    default: DebugLog(DF_MOD, DS_DEBUG, "unknown_80211_frame_type_0x%.2x\n", type);

  } /* end switch(type) */

}
Example #11
0
int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message)
{
	const unsigned char *p = message->options;
	const unsigned char *end = p; /* Add size later for gcc-3 issue */
	unsigned char option;
	unsigned char length;
	unsigned int len = 0;
	int i;
	int retval = -1;
	route_t *routers = NULL;
	route_t *routersp = NULL;
	route_t *static_routes = NULL;
	route_t *static_routesp = NULL;
	route_t *csr = NULL;

	end += sizeof (message->options);

	dhcp->address.s_addr = message->yiaddr;
	strlcpy (dhcp->servername, message->servername,
			 sizeof (dhcp->servername));

#define LEN_ERR \
	{ \
		logger (LOG_ERR, "invalid length %d for option %d", length, option); \
		p += length; \
		continue; \
	}

	while (p < end) {
		option = *p++;
		if (! option)
			continue;

		length = *p++;

		if (p + length >= end) {
			logger (LOG_ERR, "dhcp option exceeds message length");
			retval = -1;
			goto eexit;
		}

		switch (option) {
			case DHCP_END:
				goto eexit;

			case DHCP_MESSAGETYPE:
				retval = (int) *p;
				p += length;
				continue;

			default:
				if (length == 0) {
					logger (LOG_DEBUG, "option %d has zero length, skipping",
							option);
					continue;
				}
		}

#define LENGTH(_length) \
		if (length != _length) \
		LEN_ERR;
#define MIN_LENGTH(_length) \
		if (length < _length) \
		LEN_ERR;
#define MULT_LENGTH(_mult) \
		if (length % _mult != 0) \
		LEN_ERR;
#define GET_UINT8(_val) \
		LENGTH (sizeof (uint8_t)); \
		memcpy (&_val, p, sizeof (uint8_t));
#define GET_UINT16(_val) \
		LENGTH (sizeof (uint16_t)); \
		memcpy (&_val, p, sizeof (uint16_t));
#define GET_UINT32(_val) \
		LENGTH (sizeof (uint32_t)); \
		memcpy (&_val, p, sizeof (uint32_t));
#define GET_UINT16_H(_val) \
		GET_UINT16 (_val); \
		_val = ntohs (_val);
#define GET_UINT32_H(_val) \
		GET_UINT32 (_val); \
		_val = ntohl (_val);

		switch (option) {
			case DHCP_ADDRESS:
				GET_UINT32 (dhcp->address.s_addr);
				break;
			case DHCP_NETMASK:
				GET_UINT32 (dhcp->netmask.s_addr);
				break;
			case DHCP_BROADCAST:
				GET_UINT32 (dhcp->broadcast.s_addr);
				break;
			case DHCP_SERVERIDENTIFIER:
				GET_UINT32 (dhcp->serveraddress.s_addr);
				break;
			case DHCP_LEASETIME:
				GET_UINT32_H (dhcp->leasetime);
				break;
			case DHCP_RENEWALTIME:
				GET_UINT32_H (dhcp->renewaltime);
				break;
			case DHCP_REBINDTIME:
				GET_UINT32_H (dhcp->rebindtime);
				break;
			case DHCP_MTU:
				GET_UINT16_H (dhcp->mtu);
				/* Minimum legal mtu is 68 accoridng to RFC 2132.
				   In practise it's 576 (minimum maximum message size) */
				if (dhcp->mtu < MTU_MIN) {
					logger (LOG_DEBUG, "MTU %d is too low, minimum is %d; ignoring", dhcp->mtu, MTU_MIN);
					dhcp->mtu = 0;
				}
				break;

#undef GET_UINT32_H
#undef GET_UINT32
#undef GET_UINT16_H
#undef GET_UINT16
#undef GET_UINT8

#define GETSTR(_var) \
				MIN_LENGTH (sizeof (char)); \
				if (_var) free (_var); \
				_var = xmalloc (length + 1); \
				memcpy (_var, p, length); \
				memset (_var + length, 0, 1);
			case DHCP_HOSTNAME:
				GETSTR (dhcp->hostname);
				break;
			case DHCP_DNSDOMAIN:
				GETSTR (dhcp->dnsdomain);
				break;
			case DHCP_MESSAGE:
				GETSTR (dhcp->message);
				break;
			case DHCP_ROOTPATH:
				GETSTR (dhcp->rootpath);
				break;
			case DHCP_NISDOMAIN:
				GETSTR (dhcp->nisdomain);
				break;
#undef GETSTR

#define GETADDR(_var) \
				MULT_LENGTH (4); \
				if (! dhcp_add_address (&_var, p, length)) \
				{ \
					retval = -1; \
					goto eexit; \
				}
			case DHCP_DNSSERVER:
				GETADDR (dhcp->dnsservers);
				break;
			case DHCP_NTPSERVER:
				GETADDR (dhcp->ntpservers);
				break;
			case DHCP_NISSERVER:
				GETADDR (dhcp->nisservers);
				break;
#undef GETADDR

			case DHCP_DNSSEARCH:
				MIN_LENGTH (1);
				free (dhcp->dnssearch);
				if ((len = decode_search (p, length, NULL)) > 0) {
					dhcp->dnssearch = xmalloc (len);
					decode_search (p, length, dhcp->dnssearch);
				}
				break;

			case DHCP_CSR:
				MIN_LENGTH (5);
				free_route (csr);
				csr = decodeCSR (p, length);
				break;

			case DHCP_STATICROUTE:
				MULT_LENGTH (8);
				for (i = 0; i < length; i += 8) {
					if (static_routesp) {
						static_routesp->next = xmalloc (sizeof (route_t));
						static_routesp = static_routesp->next;
					} else
						static_routesp = static_routes = xmalloc (sizeof (route_t));
					memset (static_routesp, 0, sizeof (route_t));
					memcpy (&static_routesp->destination.s_addr, p + i, 4);
					memcpy (&static_routesp->gateway.s_addr, p + i + 4, 4);
					static_routesp->netmask.s_addr =
						getnetmask (static_routesp->destination.s_addr); 
				}
				break;

			case DHCP_ROUTERS:
				MULT_LENGTH (4); 
				for (i = 0; i < length; i += 4)
				{
					if (routersp) {
						routersp->next = xmalloc (sizeof (route_t));
						routersp = routersp->next;
					} else
						routersp = routers = xmalloc (sizeof (route_t));
					memset (routersp, 0, sizeof (route_t));
					memcpy (&routersp->gateway.s_addr, p + i, 4);
				}
				break;

#undef LENGTH
#undef MIN_LENGTH
#undef MULT_LENGTH

			default:
				logger (LOG_DEBUG, "no facility to parse DHCP code %u", option);
				break;
		}

		p += length;
	}

eexit:
	/* Fill in any missing fields */
	if (! dhcp->netmask.s_addr)
		dhcp->netmask.s_addr = getnetmask (dhcp->address.s_addr);
	if (! dhcp->broadcast.s_addr)
		dhcp->broadcast.s_addr = dhcp->address.s_addr | ~dhcp->netmask.s_addr;

	/* If we have classess static routes then we discard
	   static routes and routers according to RFC 3442 */
	if (csr) {
		dhcp->routes = csr;
		free_route (routers);
		free_route (static_routes);
	} else {
		/* Ensure that we apply static routes before routers */
		if (static_routes)
		{
			dhcp->routes = static_routes;
			static_routesp->next = routers;
		} else
			dhcp->routes = routers;
	}

	return retval;
}
Example #12
0
/** Checks for climate object and maps the climate variables to the house object variables.  
Currently Tout, RHout and solar_service flux data from TMY files are used.  If no climate object is linked,
then Tout will be set to 59 degF, RHout is set to 75% and solar_service flux will be set to zero for all orientations.
**/
int solar_service::init_climate()
{
	OBJECT *hdr = OBJECTHDR(this);
	OBJECT *obj = NULL;

	// link to climate data
	FINDLIST *climates = NULL;
	
	if (solar_service_model_tilt != PLAYERVAL)
	{
		if (weather!=NULL)
		{
			if(!gl_object_isa(weather, "climate")){
				// strcmp failure
				gl_error("weather property refers to a(n) \"%s\" object and not a climate object", weather->oclass->name);
				/*  TROUBLESHOOT
				While attempting to map a climate property, the solar_service array encountered an object that is not a climate object.
				Please check to make sure a proper climate object is present, and/or specified.  If the bug persists, please
				submit your code and a bug report via the trac website.
				*/
				return 0;
			}
			obj = weather;
		}
		else	//No weather specified, search
		{
			climates = gl_find_objects(FL_NEW,FT_CLASS,SAME,"climate",FT_END);
			if (climates==NULL)
			{
				//Ensure weather is set to NULL - catch below
				weather = NULL;
			}
			else if (climates->hit_count==0)
			{
				//Ensure weather is set to NULL - catch below
				weather = NULL;
			}
			else //climate data must have been found
			{
				if (climates->hit_count>1)
				{
					gl_warning("solar_servicepanel: %d climates found, using first one defined", climates->hit_count);
					/*  TROUBLESHOOT
					More than one climate object was found, so only the first one will be used by the solar_service array object
					*/
				}


				gl_verbose("solar_service init: climate data was found!");
				// force rank of object w.r.t climate
				obj = gl_find_next(climates,NULL);
				weather = obj;
			}
		}

		//Make sure it actually found one
		if (weather == NULL)
		{
			//Replicate above warning
			gl_warning("solar_servicepanel: no climate data found, using static data");
			/*  TROUBLESHOOT
			No climate object was found and player mode was not enabled, so the solar_service array object
			is utilizing default values for all relevant weather variables.
			*/

			//default to mock data
			static double tout=59.0, rhout=0.75, solar_service=92.902, wsout=0.0, albdefault=0.2;
			pTout = &tout;
			pRhout = &rhout;
			psolar_serviceD = &solar_service;	//Default all solar_service values to normal "optimal" 1000 W/m^2
			psolar_serviceH = &solar_service;
			psolar_serviceG = &solar_service;
			pAlbedo = &albdefault;
			pWindSpeed = &wsout;

			if (orientation_type==FIXED_AXIS)
			{
				GL_THROW("FIXED_AXIS requires a climate file!");
				/*  TROUBLESHOOT
				The FIXED_AXIS model for the PV array requires climate data to properly function.
				Please specify such data, or consider using a different tilt model.
				*/
			}
		}
		else if (!gl_object_isa(weather,"climate"))	//Semi redundant for "weather"
		{
			GL_THROW("weather object is not a climate object!");
			/*  TROUBLESHOOT
			The object specified for the weather property is not a climate object and will not work
			with the solar_service object.  Please specify a valid climate object, or let the solar_service object
			automatically connect.
			*/
		}
		else	//Must be a proper object
		{
			if((obj->flags & OF_INIT) != OF_INIT){
				char objname[256];
				gl_verbose("solar_service::init(): deferring initialization on %s", gl_name(obj, objname, 255));
				return 2; // defer
			}
			if (obj->rank<=hdr->rank)
				gl_set_dependent(obj,hdr);
		   
			pTout = (double*)GETADDR(obj,gl_get_property(obj,"temperature"));
//			pRhout = (double*)GETADDR(obj,gl_get_property(obj,"humidity"));	<---- Not used anywhere yet
			psolar_serviceD = (double*)GETADDR(obj,gl_get_property(obj,"solar_service_direct"));
			psolar_serviceH = (double*)GETADDR(obj,gl_get_property(obj,"solar_service_diffuse"));
			psolar_serviceG = (double*)GETADDR(obj,gl_get_property(obj,"solar_service_global"));
			pAlbedo = (double*)GETADDR(obj,gl_get_property(obj,"ground_reflectivity"));
			pWindSpeed = (double*)GETADDR(obj,gl_get_property(obj,"wind_speed"));

			//Should probably check these
			if (pTout==NULL)
			{
				GL_THROW("Failed to map outside temperature");
				/*  TROUBLESHOOT
				The solar_service PV array failed to map the outside air temperature.  Ensure this is
				properly specified in your climate data and try again.
				*/
			}

			//No need to error check - doesn't exist in any formulations yet
			//if (pRhout==NULL)
			//{
			//	GL_THROW("Failed to map outside relative humidity");
			//	/*  TROUBLESHOOT
			//	The solar_service PV array failed to map the outside relative humidity.  Ensure this is
			//	properly specified in your climate data and try again.
			//	*/
			//}

			if (psolar_serviceD==NULL)
			{
				GL_THROW("Failed to map direct normal solar_service radiation");
				/*  TROUBLESHOOT
				The solar_service PV array failed to map the solar_service direct normal radiation.  Ensure this is
				properly specified in your climate data and try again.
				*/
			}

			if (psolar_serviceH==NULL)
			{
				GL_THROW("Failed to map diffuse horizontal solar_service radiation");
				/*  TROUBLESHOOT
				The solar_service PV array failed to map the solar_service diffuse horizontal radiation.  Ensure this is
				properly specified in your climate data and try again.
				*/
			}

			if (psolar_serviceG==NULL)
			{
				GL_THROW("Failed to map global horizontal solar_service radiation");
				/*  TROUBLESHOOT
				The solar_service PV array failed to map the solar_service global horizontal radiation.  Ensure this is
				properly specified in your climate data and try again.
				*/
			}

			if (pAlbedo==NULL)
			{
				GL_THROW("Failed to map albedo/ground reflectance");
				/*  TROUBLESHOOT
				The solar_service PV array failed to map the ground reflectance.  Ensure this is
				properly specified in your climate data and try again.
				*/
			}

			if (pWindSpeed==NULL)
			{
				GL_THROW("Failed to map wind speed");
				/*  TROUBLESHOOT
				The solar_service PV array failed to map the wind speed.  Ensure this is
				properly specified in your climate data and try again.
				*/
			}

			//If climate data was found, check other related variables
			if (fix_angle_lat==true)
			{
				if (obj->latitude < 0)	//Southern hemisphere
				{
					//Get the latitude from the climate file
					tilt_angle = -obj->latitude;
				}
				else	//Northern
				{
					//Get the latitude from the climate file
					tilt_angle = obj->latitude;
				}
			}

			//Check the tilt angle for absurdity
			if (tilt_angle < 0)
			{
				GL_THROW("Invalid tilt_angle - tilt must be between 0 and 90 degrees");
				/*  TROUBLESHOOT
				A negative tilt angle was specified.  This implies the array is under the ground and will
				not receive any meaningful solar_service irradiation.  Please correct the tilt angle and try again.
				*/
			}
			else if (tilt_angle > 90.0)
			{
				GL_THROW("Invalid tilt angle - values above 90 degrees are unsupported!");
				/*  TROUBLESHOOT
				An tilt angle over 90 degrees (straight up and down) was specified.  Beyond this angle, the
				tilt algorithm does not function properly.  Please specific the tilt angle between 0 and 90 degrees
				and try again.
				*/
			}

			//Check the solar_service method
			if (orientation_type == FIXED_AXIS)
			{
				//See which function we want to use
				if (solar_service_model_tilt==LIUJORDAN)
				{
					//Map up the "classic" function
					calc_solar_service_radiation = (FUNCTIONADDR)(gl_get_function(obj,"calculate_solar_service_radiation_shading_degrees"));
				}
				else if (solar_service_model_tilt==SOLPOS)	//Use the solpos/Perez tilt model
				{
					//Map up the "classic" function
					calc_solar_service_radiation = (FUNCTIONADDR)(gl_get_function(obj,"calc_solpos_radiation_shading_degrees"));
				}
								
				//Make sure it was found
				if (calc_solar_service_radiation == NULL)
				{
					GL_THROW("Unable to map solar_service radiation function on %s in %s",obj->name,hdr->name);
					/*  TROUBLESHOOT
					While attempting to initialize the photovoltaic array mapping of the solar_service radiation function.
					Please try again.  If the bug persists, please submit your GLM and a bug report via the trac website.
					*/
				}

				//Check azimuth for absurdity as well
				if ((orientation_azimuth<0.0) || (orientation_azimuth > 360.0))
				{
					GL_THROW("orientation_azimuth must be a value representing a valid cardinal direction of 0 to 360 degrees!");
					/*  TROUBLESHOOT
					The orientation_azimuth property is expected values on the cardinal points degree system.  For this convention, 0 or
					360 is north, 90 is east, 180 is south, and 270 is west.  Please specify a direction within the 0 to 360 degree bound and try again.
					*/
				}

				//Map up our azimuth now too, if needed - Liu & Jordan model assumes 0 = equator facing
				if (solar_service_model_tilt == LIUJORDAN)
				{
					if (obj->latitude>0.0)	//North - "south" is equatorial facing
					{
						orientation_azimuth_corrected =  180.0 - orientation_azimuth;
					}
					else if (obj->latitude<0.0) //South - "north" is equatorial facing
					{
						gl_warning("solar_service:%s - Default solar_service position model is not recommended for southern hemisphere!",hdr->name);
						/*  TROUBLESHOOT
						The Liu-Jordan (default) solar_service position and tilt model was built around the northern
						hemisphere.  As such, operating in the southern hemisphere does not provide completely accurate
						results.  They are close, but tilted surfaces are not properly accounted for.  It is recommended
						that the solar_service_TILT_MODEL SOLPOS be used for southern hemisphere operations.
						*/

						if ((orientation_azimuth >= 0.0) && (orientation_azimuth <= 180.0))
						{
							orientation_azimuth_corrected =  orientation_azimuth;	//East positive
						}
						else if (orientation_azimuth == 360.0) //Special case for those who like 360 as North
						{
							orientation_azimuth_corrected = 0.0;
						}
						else	//Must be west
						{
							orientation_azimuth_corrected = orientation_azimuth - 360.0;
						}
					}
					else	//Equator - erm....
					{
						GL_THROW("Exact equator location of array detected - unknown how to handle orientation");
						/*  TROUBLESHOOT
						The solar_service orientation algorithm implemented inside GridLAB-D does not understand how to orient
						itself for an array exactly on the equator.  Shift it north or south a little bit to get valid results.
						*/
					}
				}
				else	//Right now only SOLPOS, which is "correct" - if another is implemented, may need another case
					orientation_azimuth_corrected = orientation_azimuth;
			}
			//Defaulted else for now - don't do anything
		}//End valid weather - mapping check
	}
	else	//Player mode, just drop a message
	{
		gl_warning("solar_service object:%s is in player mode - be sure to specify relevant values",hdr->name);
		/*  TROUBLESHOOT
		The solar_service array object is in player mode.  It will not take values from climate files or objects.
		Be sure to specify the Insolation, ambient_temperature, and wind_speed values as necessary.  It also
		will not incorporate any tilt functionality, since the Insolation value is expected to already include
		this adjustment.
		*/
	}

	return 1;
}
Example #13
0
int parse_dhcpmessage (dhcp_t *dhcp, dhcpmessage_t *message)
{
  unsigned char *p = message->options;
  unsigned char option;
  unsigned char length;
  unsigned char *end = message->options + sizeof (message->options);
  unsigned int len = 0;
  int i;
  int retval = -1;
  route_t *first_route = xmalloc (sizeof (route_t));
  route_t *route = first_route;
  route_t *last_route = NULL;
  route_t *csr = NULL;
  char classid[CLASS_ID_MAX_LEN];
  char clientid[CLIENT_ID_MAX_LEN];

  memset (first_route, 0, sizeof (route_t));

  /* The message back never has the class or client id's so we save them */
  strcpy (classid, dhcp->classid);
  strcpy (clientid, dhcp->clientid);

  free_dhcp (dhcp);
  memset (dhcp, 0, sizeof (dhcp_t));

  dhcp->address.s_addr = message->yiaddr;
  strcpy (dhcp->servername, message->servername);

  while (p < end)
    {
      option = *p++;
      if (!option)
	continue;

      length = *p++;

      if (p + length >= end)
	{
	  retval = -1;
	  goto eexit;
	}

      switch (option)
	{
	case DHCP_END:
	  goto eexit;

	case DHCP_MESSAGETYPE:
	  retval = (int) *p;
	  break;
#define GET_UINT32(_val) \
	  memcpy (&_val, p, sizeof (uint32_t));
#define GET_UINT32_H(_val) \
	  GET_UINT32 (_val); \
	  _val = ntohl (_val);
	case DHCP_ADDRESS:
	  GET_UINT32 (dhcp->address.s_addr);
	  break;
	case DHCP_NETMASK:
	  GET_UINT32 (dhcp->netmask.s_addr);
	  break;
	case DHCP_BROADCAST:
	  GET_UINT32 (dhcp->broadcast.s_addr);
	  break;
	case DHCP_SERVERIDENTIFIER:
	  GET_UINT32 (dhcp->serveraddress.s_addr);
	  break;
	case DHCP_LEASETIME:
	  GET_UINT32_H (dhcp->leasetime);
	  break;
	case DHCP_RENEWALTIME:
	  GET_UINT32_H (dhcp->renewaltime);
	  break;
	case DHCP_REBINDTIME:
	  GET_UINT32_H (dhcp->rebindtime);
	  break;
	case DHCP_MTU:
	  GET_UINT32_H (dhcp->mtu);
	  /* Minimum legal mtu is 68 */
	  if (dhcp->mtu > 0 && dhcp->mtu < 68)
	    dhcp->mtu = 68;
	  break;
#undef GET_UINT32_H
#undef GET_UINT32

#define GETSTR(_var) \
	  if (_var) free (_var); \
	  _var = xmalloc (length + 1); \
	  memcpy (_var, p, length); \
	  memset (_var + length, 0, 1);
	case DHCP_HOSTNAME:
	  GETSTR (dhcp->hostname);
	  break;
	case DHCP_DNSDOMAIN:
	  GETSTR (dhcp->dnsdomain);
	  break;
	case DHCP_MESSAGE:
	  GETSTR (dhcp->message);
	  break;
	case DHCP_ROOTPATH:
	  GETSTR (dhcp->rootpath);
	  break;
	case DHCP_NISDOMAIN:
	  GETSTR (dhcp->nisdomain);
	  break;
#undef GETSTR

#define GETADDR(_var) \
	  if (_var) free (_var); \
	  _var = xmalloc (sizeof (address_t)); \
	  dhcp_add_address (_var, p, length);
	case DHCP_DNSSERVER:
	  GETADDR (dhcp->dnsservers);
	  break;
	case DHCP_NTPSERVER:
	  GETADDR (dhcp->ntpservers);
	  break;
	case DHCP_NISSERVER:
	  GETADDR (dhcp->nisservers);
	  break;
#undef GETADDR

	case DHCP_DNSSEARCH:
	  if (dhcp->dnssearch)
	    free (dhcp->dnssearch);
	  if ((len = decode_search (p, length, NULL)))
	    {
	      dhcp->dnssearch = xmalloc (len);
	      decode_search (p, length, dhcp->dnssearch);
	    }
	  break;

	case DHCP_CSR:
	  csr = decodeCSR (p, length);
	  break;

	case DHCP_STATICROUTE:
	  for (i = 0; i < length; i += 8)
	    {
	      memcpy (&route->destination.s_addr, p + i, 4);
	      memcpy (&route->gateway.s_addr, p + i + 4, 4);
	      route->netmask.s_addr = getnetmask (route->destination.s_addr); 
	      last_route = route;
	      route->next = xmalloc (sizeof (route_t));
	      route = route->next;
	      memset (route, 0, sizeof (route_t));
	    }
	  break;

	case DHCP_ROUTERS:
	  for (i = 0; i < length; i += 4)
	    {
	      memcpy (&route->gateway.s_addr, p + i, 4);
	      last_route = route;
	      route->next = xmalloc (sizeof (route_t));
	      route = route->next;
	      memset (route, 0, sizeof (route_t));
	    }
	  break;

	default:
	  logger (LOG_DEBUG, "no facility to parse DHCP code %u", option);
	  break;
	}

      p += length;
    }

eexit:
  /* Fill in any missing fields */
  if (! dhcp->netmask.s_addr)
    dhcp->netmask.s_addr = getnetmask (dhcp->address.s_addr);
  if (! dhcp->broadcast.s_addr)
    dhcp->broadcast.s_addr = dhcp->address.s_addr | ~dhcp->netmask.s_addr;

  /* If we have classess static routes then we discard
     static routes and routers according to RFC 3442 */
  if (csr)
    {
      dhcp->routes = csr;
      free_route (first_route); 
    }
  else
    {
      dhcp->routes = first_route;
      if (last_route)
	{
	  free (last_route->next);
	  last_route->next = NULL;
	}
      else
	{
	  free_route (dhcp->routes);
	  dhcp->routes = NULL;
	}
    }

  /* The message back never has the class or client id's so we restore them */
  strcpy (dhcp->classid, classid);
  strcpy (dhcp->clientid, clientid);

  return retval;
}
EXPORT TIMESTAMP sync_player(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
{
	struct player *my = OBJECTDATA(obj,struct player);
	TIMESTAMP t1 = (TS_OPEN == my->status) ? my->next.ts : TS_NEVER;
	TIMESTAMP temp_t;

	if (my->status==TS_INIT){

		/* get local target if remote is not used and "value" is defined by the user at runtime */
		if (my->target==NULL && obj->parent == NULL)
			my->target = gl_get_property(obj,"value",NULL);

		if(player_open(obj) == 0)
		{
			gl_error("sync_player: Unable to open player file '%s' for object '%s'", my->file, obj->name?obj->name:"(anon)");
		}
		else
		{
			t1 = player_read(obj);
		}
	}
	while (my->status==TS_OPEN && t1<=t0
		&& my->next.ns==0 ) /* only use this method when not operating in subsecond mode */
	{	/* post this value */
		if (my->target==NULL)
			my->target = gl_get_property(obj->parent,my->property,NULL);
		if (my->target==NULL){
			gl_error("sync_player: Unable to find property \"%s\" in object %s", my->property, obj->name?obj->name:"(anon)");
			my->status = TS_ERROR;
		}
		if (my->target!=NULL)
		{
			OBJECT *target = obj->parent ? obj->parent : obj; /* target myself if no parent */
			gl_set_value(target,GETADDR(target,my->target),my->next.value,my->target); /* pointer => int64 */
		}
		
		/* Copy the current value into our "tracking" variable */
		my->delta_track.ns = my->next.ns;
		my->delta_track.ts = my->next.ts;
		memcpy(my->delta_track.value,my->next.value,sizeof(char256));

		t1 = player_read(obj);
	}

	/* Apply an intermediate value, if necessary - mainly for "DELTA players in non-delta situations" */
	if ((my->target!=NULL) && (my->delta_track.ts<t0) && (my->delta_track.ns!=0))
	{
		OBJECT *target = obj->parent ? obj->parent : obj; /* target myself if no parent */
		gl_set_value(target,GETADDR(target,my->target),my->delta_track.value,my->target); /* pointer => int64 */
	}

	/* Delta-mode catch - if we're not explicitly in delta mode and a nano-second values pops up, try to advance past it */
	if (((obj->flags & OF_DELTAMODE)!=OF_DELTAMODE) && (my->next.ns != 0) && (my->status==TS_OPEN))
	{
		/* Initial value for next time */
		temp_t = t1;

		/* Copied verbatim from above - just in case it still needs to be done - if a first timestep is a deltamode timestep */
		if (my->target==NULL)
			my->target = gl_get_property(obj->parent,my->property,NULL);
		if (my->target==NULL){
			gl_error("sync_player: Unable to find property \"%s\" in object %s", my->property, obj->name?obj->name:"(anon)");
			my->status = TS_ERROR;
		}

		/* Advance to a zero */
		while ((my->next.ns != 0) && (my->next.ts<=t0))
		{
			/* Post the value as we go, so the "final" is correct */
			/* Apply the "current value", if it is relevant (player_next_value contains the previous, so this will override it) */
			if ((my->target!=NULL) && (my->next.ts<t0))
			{
				OBJECT *target = obj->parent ? obj->parent : obj; /* target myself if no parent */
				gl_set_value(target,GETADDR(target,my->target),my->next.value,my->target); /* pointer => int64 */
			}

			/* Copy the value into the tracking variable */
			my->delta_track.ns = my->next.ns;
			my->delta_track.ts = my->next.ts;
			memcpy(my->delta_track.value,my->next.value,sizeof(char256));

			/* Perform the update */
			temp_t = player_read(obj);
		}

		/* Apply the update */
		t1 = temp_t;
	}
	else if (((obj->flags & OF_DELTAMODE)==OF_DELTAMODE) && (delta_mode_needed<t0))	/* Code to catch when gets stuck in deltamode (exits early) */
	{
		if (my->next.ts<t0)
		{
			/* Advance to a value bigger than t0 */
			while ((my->next.ns != 0) && (my->next.ts<=t0))
			{
				/* Post the value as we go, so the "final" is correct */
				/* Apply the "current value", if it is relevant (player_next_value contains the previous, so this will override it) */
				if ((my->target!=NULL) && (my->next.ts<t0))
				{
					OBJECT *target = obj->parent ? obj->parent : obj; /* target myself if no parent */
					gl_set_value(target,GETADDR(target,my->target),my->next.value,my->target); /* pointer => int64 */
				}

				/* Copy the value into the tracking variable */
				my->delta_track.ns = my->next.ns;
				my->delta_track.ts = my->next.ts;
				memcpy(my->delta_track.value,my->next.value,sizeof(char256));

				/* Perform the update */
				temp_t = player_read(obj);
			}

			/* Do the adjustment of return */
			if (t1 < t0)	/* Sometimes gets stuck */
			{
				/* Force it forward */
				t1 = temp_t;
			}
			else	/* Equal or greater than next time */
			{
				if ((temp_t<t1) && (temp_t>t0))
					t1 = temp_t;
			}
		}
		else if (my->next.ts == t0)
		{
			/* Roll it once */
			/* Copy the value into the tracking variable */
			my->delta_track.ns = my->next.ns;
			my->delta_track.ts = my->next.ts;
			memcpy(my->delta_track.value,my->next.value,sizeof(char256));

			/* Perform the update */
			temp_t = player_read(obj);
		}
	}

	/* See if we need to push a sooner update (DELTA round)*/
	if ((my->delta_track.ts!=TS_NEVER) && (my->delta_track.ns != 0))
	{
		/* Round the timestep up */
		temp_t = my->delta_track.ts+1;

		/* Make sure it is still valid - don't want to get stuck iterating */
		if ((temp_t<t1) && (temp_t>t0))
			t1 = temp_t;
	}

	/* Catch for next delta instances that may occur -- if doesn't pass a reiteration, gets missed when nothing driving*/
	if ((obj->flags & OF_DELTAMODE) == OF_DELTAMODE)
	{
		if ((t1>t0) && (my->next.ts==t0) && (my->next.ns != 0))
		{
			/* Return us here, deltamode should have been flagged */
			t1 = t0;
		}

		/* Check for a final stoppping point -- if player value goes ns beyond current stop time, it will get stuck and iterate */
		if ((my->next.ts == gl_globalstoptime) && (my->next.ns != 0) && (t1 == gl_globalstoptime))
		{
			/* Push it one second forward, just so GLD thinks it's done and can get out */
			t1 = t1 + 1;
		}
	}

	obj->clock = t0;
	return t1;
}
int
wei_get_mib_object(const mib_id_t *mib_id, 
                   mib_object_entry_t *entry)
{
   mib_object_reference_type_t type;
   mib_object_size_description_t sdesc;
   uint32_t addr;
   uint32_t size;
   unsigned int mib_id_index = 0;
   unsigned int component;
   unsigned int final_component;
   unsigned int index;
   unsigned int nentries;
   mib_object_entry_t *oe;

   if(mibtable == NULL || mib_id == NULL || entry == NULL)
   {
      return WIFI_ENGINE_FAILURE;
   }

   index = mibtable->rootindex;
   nentries = mibtable->rootentries;
   component = (unsigned int)(mib_id->octets[0]) - 1;

   while(1) {
      final_component = (mib_id_index >= MIB_IDENTIFIER_MAX_LENGTH - 1)
         || (mib_id->octets[mib_id_index + 1] == 0);

      if(component >= nentries) {
         DE_TRACE_STATIC(TR_MIB, "component too large\n");
         return WIFI_ENGINE_FAILURE;
      }
      index += component;
      if(index >= mibtable->size / MIBENTRYSIZE) {
         DE_TRACE_STATIC(TR_MIB, "bad address\n");
         return WIFI_ENGINE_FAILURE;
      }
      oe = &mibtable->table[index];
      type = (mib_object_reference_type_t)GETFIELD(oe->storage_description, REFERENCE_TYPE);
      sdesc = (mib_object_size_description_t)GETFIELD(oe->storage_description, OBJECT_SIZE_DESCRIPTION);
      addr = GETADDR(oe->reference);
      size = GETFIELD(oe->storage_description, OBJECT_SIZE);

      if(type == MIB_OBJECT_REFERENCE_TYPE_MIB_TABLE) {
         if(final_component) {
            DE_TRACE_STATIC(TR_MIB, "non-leaf\n");
            return WIFI_ENGINE_FAILURE;
         }
         if(sdesc != MIB_OBJECT_SIZE_DESCRIPTION_FIXED_SIZE) {
            DE_TRACE_STATIC(TR_MIB, "unexpected size description type\n");
            return WIFI_ENGINE_FAILURE;
         }
         if(!ADDRVALID(addr, mibtable)) {
            DE_TRACE_STATIC(TR_MIB, "bad address\n");
            return WIFI_ENGINE_FAILURE;
         }
         index = ADDRTOINDEX(addr, mibtable);
         nentries = size;
         mib_id_index++;
         component = (unsigned int)(mib_id->octets[mib_id_index]) - 1;
         continue;
      } else if(type == MIB_OBJECT_REFERENCE_TYPE_MIB_SUBTABLE) {
         if(sdesc != MIB_OBJECT_SIZE_DESCRIPTION_FIXED_SIZE) {
            DE_TRACE_STATIC(TR_MIB, "unexpected size description type\n");
            return WIFI_ENGINE_FAILURE;
         }
         if(size != 2) {
            DE_TRACE_INT(TR_MIB, "unexpected subtable size (%u)\n", size);
            return WIFI_ENGINE_FAILURE;
         }
         if(!ADDRVALID(addr, mibtable)) {
            DE_TRACE_STATIC(TR_MIB, "bad address\n");
            return WIFI_ENGINE_FAILURE;
         }
         index = ADDRTOINDEX(addr, mibtable);
         nentries = size;
         if(final_component) {
            component = 0;
         } else {
            component = 1;
         }
         continue;
      } else {
         if(!final_component) {
            DE_TRACE_STATIC(TR_MIB, "leaf with more components\n");
            return WIFI_ENGINE_FAILURE;
         }
         *entry = *oe;
         break;
      }
   }
   return WIFI_ENGINE_SUCCESS;
}
Example #16
0
int windturb_dg::init(OBJECT *parent)
{
	OBJECT *obj = OBJECTHDR(this);

	double ZB, SB, EB;
	complex tst, tst2, tst3, tst4;

	switch (Turbine_Model)	{
		case GENERIC_IND_LARGE:
		case GENERIC_SYNCH_LARGE:	//Creates generic 1.5 MW wind turbine.
			blade_diam = 82.5;
			turbine_height = 90;
			q = 3;						//number of gearbox stages
			Rated_VA = 1635000;
			Max_P = 1500000;
			Max_Q = 650000;
			Rated_V = 600;
			pf = 0.95;
			CP_Data = GENERAL_LARGE;
			cut_in_ws = 4;			//lowest wind speed 
			cut_out_ws = 25;		//highest wind speed 
			Cp_max = 0.302;			//rotor specifications for power curve
			ws_maxcp = 7;			
			Cp_rated = Cp_max-.05;	
			ws_rated = 12.5;		
			if (Turbine_Model == GENERIC_IND_LARGE) {
				Gen_type = INDUCTION;
				Rst = 0.12;					
				Xst = 0.17;					
				Rr = 0.12;				
				Xr = 0.15;			
				Rc = 999999;		
				Xm = 9.0;	
			}
			else if (Turbine_Model == GENERIC_SYNCH_LARGE) {
				Gen_type = SYNCHRONOUS;
				Rs = 0.05;
				Xs = 0.200;
				Rg = 0.000;
				Xg = 0.000;
			}
			break;
		case GENERIC_IND_MID:
		case GENERIC_SYNCH_MID:	//Creates generic 100kW wind turbine, northwind 100
			blade_diam = 23.2;   //in m
			turbine_height = 30;   //in m
			q = 0;						//number of gearbox stages, no gear box 
			Rated_VA = 156604;
			Max_P = 150000;
			Max_Q = 45000;
			Rated_V = 480;  
			pf = 0.9;     ///lag and lead of 0.9
			CP_Data = GENERAL_MID;
			cut_in_ws = 3.5;			//lowest wind speed in m/s
			cut_out_ws = 25;		   //highest wind speed in m/s
			Cp_max = 0.302;			  //rotor specifications for power curve
			ws_maxcp = 7;			
			Cp_rated = Cp_max-.05;	
			ws_rated = 14.5;		//	in m/s
			if (Turbine_Model == GENERIC_IND_MID) {     // need to check the machine parameters
				Gen_type = INDUCTION;
				Rst = 0.12;					
				Xst = 0.17;					
				Rr = 0.12;				
				Xr = 0.15;			
				Rc = 999999;		
				Xm = 9.0;	
			}
			else if (Turbine_Model == GENERIC_SYNCH_MID) {
				Gen_type = SYNCHRONOUS;
				Rs = 0.05;
				Xs = 0.200;
				Rg = 0.000;
				Xg = 0.000;
			}
			break;
		case GENERIC_IND_SMALL:					
		case GENERIC_SYNCH_SMALL:	//Creates generic 5 kW wind turbine, Fortis Montana 5 kW wind turbine
			blade_diam = 5;      // in m
			turbine_height = 16;   //in m
			q = 0;						//number of gearbox stages, no gear box
			Rated_VA = 6315;               // calculate from P & Q
			Max_P = 5800; 
			Max_Q = 2500;
			Rated_V = 600;
			pf = 0.95;
			CP_Data = GENERAL_SMALL;
			cut_in_ws = 2.5;			//lowest wind speed 
			cut_out_ws = 25;		//highest wind speed 
			Cp_max = 0.302;			//rotor specifications for power curve
			ws_maxcp = 7;			//	|
			Cp_rated = Cp_max-.05;	//	|
			ws_rated = 17;		//	|
			if (Turbine_Model == GENERIC_IND_SMALL) {
				Gen_type = INDUCTION;
				Rst = 0.12;					
				Xst = 0.17;					
				Rr = 0.12;				
				Xr = 0.15;			
				Rc = 999999;		
				Xm = 9.0;	
			}
			else if (Turbine_Model == GENERIC_SYNCH_SMALL) {
				Gen_type = SYNCHRONOUS;
				Rs = 0.05;
				Xs = 0.200;
				Rg = 0.000;
				Xg = 0.000;
			}
			break;
		case VESTAS_V82:	//Include manufacturer's data - cases can be added to call other wind turbines
			turbine_height = 78;
			blade_diam = 82;
			Rated_VA = 1808000;
			Rated_V = 600;
			Max_P = 1650000;
			Max_Q = 740000;
			pf = 0.91;		//Can range between 0.65-1.00 depending on controllers and Pout.
			CP_Data = MANUF_TABLE;		
			cut_in_ws = 3.5;
			cut_out_ws = 20;
			q = 2;
			Gen_type = SYNCHRONOUS;	//V82 actually uses a DFIG, but will use synch representation for now
			Rs = 0.025;				//Estimated values for synch representation.
			Xs = 0.200;
			Rg = 0.000;
			Xg = 0.000;
			break;
		case GE_25MW:
			turbine_height = 100;
			blade_diam = 100;
			Rated_VA = 2727000;
			Rated_V = 690;
			Max_P = 2500000;
			Max_Q = 1090000;
			pf = 0.95;		//ranges between -0.9 -> 0.9;
			q = 3;
			CP_Data = GENERAL_LARGE;
			cut_in_ws = 3.5;
			cut_out_ws = 25;
			Cp_max = 0.28;
			Cp_rated = 0.275;
			ws_maxcp = 8.2;
			ws_rated = 12.5;
			Gen_type = SYNCHRONOUS;
			Rs = 0.035;
			Xs = 0.200;
			Rg = 0.000;
			Xg = 0.000;
			break;
		case BERGEY_10kW:
			turbine_height = 24;
			blade_diam = 7;
			Rated_VA = 10000;
			Rated_V = 360;
			Max_P = 15000;
			Max_Q = 4000;
			pf = 0.95;		//ranges between -0.9 -> 0.9;
			q = 0;
			CP_Data = GENERAL_SMALL;
			cut_in_ws = 2;
			cut_out_ws = 20;
			Cp_max = 0.28;
			Cp_rated = 0.275;
			ws_maxcp = 8.2;
			ws_rated = 12.5;
			Gen_type = SYNCHRONOUS;
			Rs = 0.05;
			Xs = 0.200;
			Rg = 0.000;
			Xg = 0.000;
			break;
		case USER_DEFINED:

			CP_Data = USER_SPECIFY;	

			Gen_type = USER_TYPE;
			Rs = 0.2;
			Xs = 0.2;
			Rg = 0.1;
			Xg = 0;

			if (turbine_height <=0)
				GL_THROW ("turbine height cannot have a negative or zero value.");
			/*  TROUBLESHOOT
			Turbine height must be specified as a value greater than or equal to zero.
			*/
			if (blade_diam <=0)
				GL_THROW ("blade diameter cannot have a negative or zero value.");
			/*  TROUBLESHOOT
			Blade diameter must be specified as a value greater than or equal to zero.
			*/
			if (cut_in_ws <=0)
				GL_THROW ("cut in wind speed cannot have a negative or zero value.");
			/*  TROUBLESHOOT
			Cut in wind speed must be specified as a value greater than or equal to zero.
			*/
			if (cut_out_ws <=0)
				GL_THROW ("cut out wind speed cannot have a negative or zero value.");
			/*  TROUBLESHOOT
			Cut out wind speed must be specified as a value greater than or equal to zero.
			*/
			if (ws_rated <=0)
				GL_THROW ("rated wind speed cannot have a negative or zero value.");
			/*  TROUBLESHOOT
			Rated wind speed must be specified as a value greater than or equal to zero.
			*/
			if (ws_maxcp <=0)
				GL_THROW ("max cp cannot have a negative or zero value.");
			/*  TROUBLESHOOT
			Maximum coefficient of performance must be specified as a value greater than or equal to zero.
			*/
			break;
		default:
			GL_THROW("Unknown turbine model was specified");
			/*  TROUBLESHOOT
			An unknown wind turbine model was selected.  Please select a Turbine_Model from the available list.
			*/
	}

	// construct circuit variable map to meter -- copied from 'House' module
	struct {
		complex **var;
		char *varname;
	} map[] = {
		// local object name,	meter object name
		{&pCircuit_V,			"voltage_A"}, // assumes 2 and 3 follow immediately in memory
		{&pLine_I,				"current_A"}, // assumes 2 and 3(N) follow immediately in memory
		/// @todo use triplex property mapping instead of assuming memory order for meter variables (residential, low priority) (ticket #139)
	};

	static complex default_line123_voltage[3], default_line1_current[3];
	int i;

	//Map phases
	set *phaseInfo;
	PROPERTY *tempProp;
	tempProp = gl_get_property(parent,"phases");

	if ((tempProp==NULL || tempProp->ptype!=PT_set))
	{
		GL_THROW("Unable to map phases property - ensure the parent is a powerflow:meter");
		/*  TROUBLESHOOT
		While attempting to map the phases property from the parent object, an error was encountered.
		Please check and make sure your parent object is a meter inside the powerflow module and try
		again.  If the error persists, please submit your code and a bug report via the Trac website.
		*/
	}
	else
		phaseInfo = (set*)GETADDR(parent,tempProp);

	int temp_phases=0;

	// Currently only supports 3-phase connection, so check number of phases of parent
	if ((*phaseInfo & PHASE_A) == PHASE_A)
		temp_phases += 1;
	if ((*phaseInfo & PHASE_B) == PHASE_B)
		temp_phases += 1;
	if ((*phaseInfo & PHASE_C) == PHASE_C)
		temp_phases += 1;

	if (temp_phases < 3)
		GL_THROW("The wind turbine model currently only supports a 3-phase connection, please check meter connection");
	/*  TROUBLESHOOT
	Currently the wind turbine model only supports 3-phase connnections. Please attach to 3-phase meter.
	*/



	// find parent meter, if not defined, use a default meter (using static variable 'default_meter')
	if (parent!=NULL)
	{
		if((parent->flags & OF_INIT) != OF_INIT){
			char objname[256];
			gl_verbose("windturb_dg::init(): deferring initialization on %s", gl_name(parent, objname, 255));
			return 2; // defer
		}
		if (gl_object_isa(parent,"meter","powerflow"))	//Attach to meter
		{
			/*
			NR_mode = get_bool(parent,"NR_mode");

			//Check NR_mode, just to be consistent
			if (NR_mode == NULL)
			{
				GL_THROW("Wind turbine failed to map NR_mode property");
				*/
				/*  TROUBLESHOOT
				While attempting to map up the NR_mode property, an error
				was encountered.  Please try again.  If the error persists,
				please submit your code and a bug report via the trac website.
				*/
			/*
			}
		*/

			//Map the voltages
			double *parNominalVoltage;

			tempProp = gl_get_property(parent,"nominal_voltage");
			if ((tempProp==NULL || tempProp->ptype!=PT_double))
			{
				GL_THROW("Unable to map nominal_voltage property - ensure the parent is a powerflow:meter");
				/*  TROUBLESHOOT
				While attempting to map the nominal_voltage property from the parent object, an error was encountered.
				Please check and make sure your parent object is a meter inside the powerflow module and try
				again.  If the error persists, please submit your code and a bug report via the Trac website.
				*/
			}
			else
				parNominalVoltage = (double*)GETADDR(parent,tempProp);

			// check nominal voltage against rated voltage
			if ( fabs(1 - (*parNominalVoltage * sqrt(3.0) / Rated_V) ) > 0.1 )
				gl_warning("windturb_dg (id:%d, name:%s): Rated generator voltage (LL: %.1f) and nominal voltage (LL: %.1f) of meter parent are different by greater than 10 percent. Odd behavior may occur.",obj->id,obj->name,Rated_V,*parNominalVoltage * sqrt(3.0));
			/* TROUBLESHOOT
			Currently, the model allows you to attach the turbine to a voltage that is quite different than the rated terminal
			voltage of the generator.  However, this may cause odd behavior, as the solved powerflow voltage is used to calculate
			the generator induced voltages and conversion from mechanical power.  It is recommended that the nominal
			voltages of the parent meter be within ~10% of the rated voltage.
			*/

			// attach meter variables to each circuit
			for (i=0; i<sizeof(map)/sizeof(map[0]); i++)
			{
				*(map[i].var) = get_complex(parent,map[i].varname);

				if (*(map[i].var) == NULL)
				{
					GL_THROW("Unable to map variable %s",map[i].varname);
					/*  TROUBLESHOOT
					The variable name was not found when mapping it
					*/
				}
			}
		}
		else if (gl_object_isa(parent,"triplex_meter","powerflow"))
		{
			GL_THROW("The wind turbine model does currently support direct connection to single phase or triplex meters. Connect through a rectifier-inverter combination.");
			/*  TROUBLESHOOT
			This model does not currently support connection to a triplex system.  Please connect to a 3-phase meter.
			*/

			//Map voltage
			pCircuit_V = get_complex(parent,"voltage_1");

			//Make sure it worked
			if (pCircuit_V == NULL)
				GL_THROW("Unable to map triplex_meter voltage");

			//Map current
			pLine_I = get_complex(parent,"current_1");

			//Make sure it worked
			if (pLine_I == NULL)
				GL_THROW("Unable to map triplex_meter current");

			//NR_mode = get_bool(parent,"NR_mode");
		}
		else if (gl_object_isa(parent,"rectifier","generators"))
		{

			//Map the voltages
			double *parNominalVoltage;

			tempProp = gl_get_property(parent,"V_Rated");
			if ((tempProp==NULL || tempProp->ptype!=PT_double))
			{
				GL_THROW("Unable to map V_Rated property - ensure the parent is a powerflow:meter");
				/*  TROUBLESHOOT
				While attempting to map the nominal_voltage property from the parent object, an error was encountered.
				Please check and make sure your parent object is a meter inside the powerflow module and try
				again.  If the error persists, please submit your code and a bug report via the Trac website.
				*/
			}
			else
				parNominalVoltage = (double*)GETADDR(parent,tempProp);

			// check nominal voltage against rated voltage
			if ( fabs(1 - (*parNominalVoltage / Rated_V) ) > 0.1 )
				gl_warning("windturb_dg (id:%d, name:%s): Rated generator voltage (LL: %.1f) and nominal voltage (LL: %.1f) of meter parent are different by greater than 10 percent. Odd behavior may occur.",obj->id,obj->name,Rated_V,*parNominalVoltage * sqrt(3.0));
			/* TROUBLESHOOT
			Currently, the model allows you to attach the turbine to a voltage that is quite different than the rated terminal
			voltage of the generator.  However, this may cause odd behavior, as the solved powerflow voltage is used to calculate
			the generator induced voltages and conversion from mechanical power.  It is recommended that the nominal
			voltages of the parent meter be within ~10% of the rated voltage.
			*/



			// attach meter variables to each circuit
			for (i=0; i<sizeof(map)/sizeof(map[0]); i++)
			{
				if ((*(map[i].var) = get_complex(parent,map[i].varname))==NULL)
				{
					GL_THROW("%s (%s:%d) does not implement rectifier variable %s for %s (windturb_dg:%d)", 
						/*	TROUBLESHOOT
						The rectifier requires that the inverter contains certain published properties in order to properly connect. If you encounter this error, please report it to the developers, along with
						the version of GridLAB-D that raised this error.
						*/
						parent->name?parent->name:"unnamed object", parent->oclass->name, parent->id, map[i].varname, obj->name?obj->name:"unnamed", obj->id);
				}
			}

		}
		else
		{
			GL_THROW("windturb_dg (id:%d): Invalid parent object",obj->id);
			/* TROUBLESHOOT 
			The wind turbine object must be attached a 3-phase meter object.  Please check parent of object.
			*/
		}
	}
	else
	{
		gl_warning("windturb_dg:%d %s", obj->id, parent==NULL?"has no parent meter defined":"parent is not a meter");	

		// attach meter variables to each circuit in the default_meter
		*(map[0].var) = &default_line123_voltage[0];
		*(map[1].var) = &default_line1_current[0];

		// provide initial values for voltages
		default_line123_voltage[0] = complex(Rated_V/sqrt(3.0),0);
		default_line123_voltage[1] = complex(Rated_V/sqrt(3.0)*cos(2*PI/3),Rated_V/sqrt(3.0)*sin(2*PI/3));
		default_line123_voltage[2] = complex(Rated_V/sqrt(3.0)*cos(-2*PI/3),Rated_V/sqrt(3.0)*sin(-2*PI/3));

		NR_mode = &default_NR_mode;
	}

	if (Gen_status==OFFLINE)
	{
		gl_warning("init_windturb_dg (id:%d,name:%s): Generator is out of service!", obj->id,obj->name); 	
	}	

	if (Gen_type == SYNCHRONOUS || Gen_type == INDUCTION)
	{
		if (Gen_mode == CONSTANTE)
		{
			gl_warning("init_windturb_dg (id:%d,name:%s): Synchronous and induction generators in constant voltage mode has not been fully tested and my not work properly.", obj->id,obj->name);
		}
	}

	if (Rated_VA!=0.0)  
		SB = Rated_VA/3;
	if (Rated_V!=0.0)  
		EB = Rated_V/sqrt(3.0);
	if (SB!=0.0)  
		ZB = EB*EB/SB;
	else 
		GL_THROW("Generator power capacity not specified!");
	/* TROUBLESHOOT 
	Rated_VA of generator must be specified so that per unit values can be calculated
	*/

	if (Gen_type == INDUCTION)  
	{
		complex Zrotor(Rr,Xr);
		complex Zmag = complex(Rc*Xm*Xm/(Rc*Rc + Xm*Xm),Rc*Rc*Xm/(Rc*Rc + Xm*Xm));
		complex Zstator(Rst,Xst);

		//Induction machine two-port matrix.
		IndTPMat[0][0] = (Zmag + Zstator)/Zmag;
		IndTPMat[0][1] = Zrotor + Zstator + Zrotor*Zstator/Zmag;
		IndTPMat[1][0] = complex(1,0) / Zmag;
		IndTPMat[1][1] = (Zmag + Zrotor) / Zmag;
	}

	else if (Gen_type == SYNCHRONOUS)  
	{
		double Real_Rs = Rs * ZB; 
		double Real_Xs = Xs * ZB;
		double Real_Rg = Rg * ZB; 
		double Real_Xg = Xg * ZB;
		tst = complex(Real_Rg,Real_Xg);
		tst2 = complex(Real_Rs,Real_Xs);
		AMx[0][0] = tst2 + tst;			//Impedance matrix
		AMx[1][1] = tst2 + tst;
		AMx[2][2] = tst2 + tst;
		AMx[0][1] = AMx[0][2] = AMx[1][0] = AMx[1][2] = AMx[2][0] = AMx[2][1] = tst;
		tst3 = (complex(1,0) + complex(2,0)*tst/tst2)/(tst2 + complex(3,0)*tst);
		tst4 = (-tst/tst2)/(tst2 + tst);
		invAMx[0][0] = tst3;			//Admittance matrix (inverse of Impedance matrix)
		invAMx[1][1] = tst3;
		invAMx[2][2] = tst3;
		invAMx[0][1] = AMx[0][2] = AMx[1][0] = AMx[1][2] = AMx[2][0] = AMx[2][1] = tst4;
	}
	else
		GL_THROW("Unknown generator type specified");
	/* TROUBLESHOOT 
	Shouldn't have been able to specify an unknown generator type.  Please report this error to GridLAB-D support.
	*/

	init_climate();

	return 1;
}
Example #17
0
/* Checks for climate object and maps the climate variables to the windturb object variables.  
If no climate object is linked, then default pressure, temperature, and wind speed will be used. */
int windturb_dg::init_climate()
{
	OBJECT *hdr = OBJECTHDR(this);

	// link to climate data
	static FINDLIST *climates = NULL;
	int not_found = 0;

	climates = gl_find_objects(FL_NEW,FT_CLASS,SAME,"climate",FT_END);
	if (climates==NULL)
	{
		not_found = 1;
		gl_warning("windturb_dg (id:%d)::init_climate(): no climate data found, using static data",hdr->id);

		//default to mock data
		static double air_dens = std_air_dens, avgWS = avg_ws, Press = std_air_press, Temp = std_air_temp;
		pWS = &avgWS;
		pPress = &Press;
		pTemp = &Temp;

	}
	else if (climates->hit_count>1)
	{
		gl_verbose("windturb_dg: %d climates found, using first one defined", climates->hit_count);
	}
	// }
	if (climates!=NULL)
	{
		if (climates->hit_count==0)
		{
			//default to mock data
			gl_warning("windturb_dg (id:%d)::init_climate(): no climate data found, using static data",hdr->id);
			static double air_dens = std_air_dens, avgWS = avg_ws, Press = std_air_press, Temp = std_air_temp;
			pWS = &avgWS;
			pPress = &Press;
			pTemp = &Temp;
		}
		else //climate data was found
		{
			// force rank of object w.r.t climate
			OBJECT *obj = gl_find_next(climates,NULL);
			if (obj->rank<=hdr->rank)
				gl_set_dependent(obj,hdr);
			pWS = (double*)GETADDR(obj,gl_get_property(obj,"wind_speed"));  
			pPress = (double*)GETADDR(obj,gl_get_property(obj,"pressure"));
			pTemp = (double*)GETADDR(obj,gl_get_property(obj,"temperature"));

			//Make sure it worked
			if (pWS==NULL)
			{
				GL_THROW("windturb_dg (id:%d): Unable to map wind_speed from climate object",obj->id);
			}
			if (pPress==NULL)
			{
				GL_THROW("windturb_dg (id:%d): Unable to map air pressure from climate object",obj->id);
			}
			if (pTemp==NULL)
			{
				GL_THROW("windturb_dg (id:%d): Unable to map air temperature from climate object",obj->id);
			}
		}
	}
	return 1;
}
int passive_controller::init(OBJECT *parent){
	
	OBJECT *hdr = OBJECTHDR(this);
	PROPERTY *enduseProperty;

	if(parent == NULL){
		gl_error("passive_controller has no parent and will be operating in 'dummy' mode");
	} else {
		if(output_state_propname[0] == 0 && output_setpoint_propname[0] == 0){
			GL_THROW("passive_controller has no output properties");
		}
		// expectation_addr
		if(expectation_object != 0){
			expectation_property = gl_get_property(expectation_object, expectation_propname);
			if(expectation_property == 0){
				GL_THROW("passive_controller cannot find its expectation property");
			}
			expectation_addr = (void *)((unsigned int64)expectation_object + sizeof(OBJECT) + (unsigned int64)expectation_property->addr);
		}

		if(observation_object != 0){
			// observation_addr
			observation_prop = gl_get_property(observation_object, observation_propname);
			if(observation_prop != 0){
				observation_addr = (void *)((unsigned int64)observation_object + sizeof(OBJECT) + (unsigned int64)observation_prop->addr);
			}
			if (pool_pump_model == false)
			{
				// observation_mean_addr
				observation_mean_prop = gl_get_property(observation_object, observation_mean_propname);
				if(observation_mean_prop != 0){
					observation_mean_addr = (void *)((unsigned int64)observation_object + sizeof(OBJECT) + (unsigned int64)observation_mean_prop->addr);
				}
				// observation_stdev_addr
				stdev_observation_property = gl_get_property(observation_object, observation_stdev_propname);
				if(stdev_observation_property != 0){
					observation_stdev_addr = (void *)((unsigned int64)observation_object + sizeof(OBJECT) + (unsigned int64)stdev_observation_property->addr);
				}
			}

		}
		// output_state
		if(output_state_propname[0] != 0){
			output_state_prop = gl_get_property(parent, output_state_propname);
			if(output_state_prop == NULL){
				GL_THROW("passive_controller parent \"%s\" does not contain property \"%s\"", 
					(parent->name ? parent->name : "anon"), output_state_propname.get_string());
			}
			output_state_addr = (void *)((unsigned int64)parent + sizeof(OBJECT) + (unsigned int64)output_state_prop->addr);
		}
		
		// output_setpoint
		if (control_mode != this->CM_PROBOFF && control_mode != this->CM_ELASTICITY_MODEL)
		{
			if(output_setpoint_propname[0] == 0 && output_setpoint_propname[0] == 0){
				GL_THROW("passive_controller has no output properties");
			}
			if(output_setpoint_propname[0] != 0){
				output_setpoint_property = gl_get_property(parent, output_setpoint_propname);
				if(output_setpoint_property == NULL){
					GL_THROW("passive_controller parent \"%s\" does not contain property \"%s\"", 
						(parent->name ? parent->name : "anon"), output_setpoint_propname.get_string());
				}
				output_setpoint_addr = (void *)((unsigned int64)parent + sizeof(OBJECT) + (unsigned int64)output_setpoint_property->addr);
			}
		}
	}

	if (pool_pump_model == false && control_mode != CM_ELASTICITY_MODEL)
		gl_set_dependent(hdr, expectation_object);
	gl_set_dependent(hdr, observation_object);

	if(observation_object == NULL){
		GL_THROW("passive_controller observation_object object is undefined, and can not function");
	}
	
	//
	// make sure that the observation_object and expectable are ranked above the controller
	//

	if(base_setpoint != 0.0){
		orig_setpoint = 1;
	}

	if (pool_pump_model == true)
	{
		if (control_mode != CM_DUTYCYCLE)
			GL_THROW("pool pump mode must be used with control mode set to DUTYCYCLE");
		if (firstTierHours == 0 || secondTierHours == 0)
			GL_THROW("Please set first and second tier hours in pool pump duty cycle mode");
		if (firstTierPrice == 0 || secondTierPrice == 0)
			GL_THROW("Please set first and second tier prices in pool pump duty cycle mode");
	}

	if(dPeriod == 0.0){
		dPeriod = 300.0;
		period = 300; // five minutes
	} else {
		period = (TIMESTAMP)floor(dPeriod + 0.5);
	}

	if (gl_object_isa(parent,"ZIPload","residential"))
	{
		zipLoadParent = true;
	}
	
	if(zipLoadParent == true && control_mode == CM_ELASTICITY_MODEL){
	
		ThirdTierArraySize = 0;
		SecondTierArraySize = 0;
		FirstTierArraySize = 0;

		elasticityPeriod = 24;

		if(subElasticityFirstSecond > 0)
			gl_warning("The peak to offpeak Substitution Elasticity is positive.  While this is allowed, it is typically the reverse of convention, as an increase in peak to offpeak price ratio generally produces a reduction in peak load to offpeak load. This is indicated by a negative peak to offpeak Substitution Elasticity value.");

		if(subElasticityFirstThird > 0)
			gl_warning("The critical peak to offpeak Substitution Elasticity is positive.  While this is allowed, it is typically the reverse of convention, as an increase in critical peak to offpeak price ratio generally produces a reduction in peak load to offpeak load. This is indicated by a negative critical peak to offpeak Substitution Elasticity value.");

		if(dailyElasticity > 0)
			gl_warning("The Daily Elasticity is positive.  While this is allowed, it is typically the reverse of convention, as an increase in daily price generally produces a reduction in daily load. This is indicated by a negative Daily Elasticity value.");

		if(critical_day >= 0.5){

			if (firstTierPrice == 0)
					GL_THROW("Please set first tier price in the Elasticity Model");

			if (oldFirstTierPrice == 0)
					GL_THROW("Please set old first tier price in the Elasticity Model");

				
			if (thirdTierHours == 0)
				GL_THROW("Please set third tier hours in the Elasticity Model");

			if (thirdTierPrice == 0)
				GL_THROW("Please set third tier price in the Elasticity Model");

			if (oldThirdTierPrice == 0){

				oldThirdTierPrice = oldFirstTierPrice;
				gl_warning("Old third tier price is missing. System will assume the old pricing scheme was a fixed pricing scheme and use the old first tier price");

			}

			if(check_two_tier_cpp != true){
				
				if (secondTierHours == 0)
					GL_THROW("Please set second tier hours in the Elasticity Model");

				if (secondTierPrice == 0)
					GL_THROW("Please set second tier price in the Elasticity Model");

				if (oldSecondTierPrice == 0){

					oldSecondTierPrice = oldFirstTierPrice;
					gl_warning("Old second tier price is missing. System will assume the old pricing scheme was a fixed pricing scheme and use the old first tier price");

				}				
				
				if(firstTierHours == 0){
					firstTierHours = elasticityPeriod - thirdTierHours - secondTierHours;
				}
				else{
					if((thirdTierHours+secondTierHours+firstTierHours) != elasticityPeriod)
					GL_THROW("Please set the tier hours correctly in the Elasticity Model");
				}

				SecondTierArraySize = (int)(((secondTierHours * 3600) / period));

				//Calculation of the price ratios and change in price ratios.
				//This will not change for the course of the simulation
				oldPriceRatioSecondFirst = oldSecondTierPrice/oldFirstTierPrice;
				newPriceRatioSecondFirst = secondTierPrice/firstTierPrice;

				if(linearizeElasticity == true)
				{
					peakPriceMultiplier = pow(newPriceRatioSecondFirst/oldPriceRatioSecondFirst,subElasticityFirstSecond);
				}
				else{

					peakPriceMultiplier = 1 + ((subElasticityFirstSecond)*(newPriceRatioSecondFirst-oldPriceRatioSecondFirst)/oldPriceRatioSecondFirst);
					priceDiffSecond = secondTierPrice - oldSecondTierPrice; 
				}

			}
			else{

				if(firstTierHours == 0){
					firstTierHours = elasticityPeriod - thirdTierHours;
				}
				else{
					if((thirdTierHours+firstTierHours) != elasticityPeriod)
					GL_THROW("Please set the tier hours correctly in the Elasticity Model");
				}					
			}

			ThirdTierArraySize = (int)(((thirdTierHours * 3600) / period));			

			//Calculation of the price ratios and change in price ratios.
			//This will not change for the course of the simulation
			oldPriceRatioThirdFirst = oldThirdTierPrice/oldFirstTierPrice;
			newPriceRatioThirdFirst = thirdTierPrice/firstTierPrice;

			if(linearizeElasticity == true)
			{
				criticalPriceMultiplier = pow(newPriceRatioThirdFirst/oldPriceRatioThirdFirst,subElasticityFirstThird);
			}
			else{

				criticalPriceMultiplier = 1 + ((subElasticityFirstThird)*(newPriceRatioThirdFirst-oldPriceRatioThirdFirst)/oldPriceRatioThirdFirst);
				priceDiffThird = thirdTierPrice - oldThirdTierPrice; 	
			}

		}
		else{			

			if (firstTierPrice == 0)
					GL_THROW("Please set first tier price in the Elasticity Model");

			if (oldFirstTierPrice == 0)
					GL_THROW("Please set old first tier price in the Elasticity Model");
			
			if(firstTierHours == 0){
				firstTierHours = elasticityPeriod - secondTierHours;
			}
			else{
				if((secondTierHours+firstTierHours) != elasticityPeriod)
				GL_THROW("Please set the tier hours correctly in the Elasticity Model");
			}

			if (secondTierHours == 0)
				GL_THROW("Please set second tier hours in the Elasticity Model");

			if (secondTierPrice == 0)
				GL_THROW("Please set second tier price in the Elasticity Model");

			if (oldSecondTierPrice == 0){
					oldSecondTierPrice = oldFirstTierPrice;
					gl_warning("Old second tier price is missing. System will assume the old pricing scheme was a fixed pricing scheme and use the old first tier price");
			}

			SecondTierArraySize = (int)(((secondTierHours * 3600) / period));
				
			//Calculation of the price ratios and change in price ratios.
			//This will not change for the course of the simulation
			oldPriceRatioSecondFirst = oldSecondTierPrice/oldFirstTierPrice;
			newPriceRatioSecondFirst = secondTierPrice/firstTierPrice;

			if(linearizeElasticity == true)
			{
				peakPriceMultiplier = pow(newPriceRatioSecondFirst/oldPriceRatioSecondFirst,subElasticityFirstSecond);
			}
			else{
				peakPriceMultiplier = 1 + ((subElasticityFirstSecond)*(newPriceRatioSecondFirst-oldPriceRatioSecondFirst)/oldPriceRatioSecondFirst);
				priceDiffSecond = secondTierPrice - oldSecondTierPrice; 				
			}
		}

		FirstTierArraySize = (int)(((firstTierHours * 3600) / period));

		priceDiffFirst = firstTierPrice - oldFirstTierPrice; 	
	
		ArraySize = (int)(((elasticityPeriod * 3600) / period));

		if(price_offset==0) price_offset = 10E-6 ;	
		
		tier_prices = (double *)gl_malloc(ArraySize*sizeof(double));

		if (tier_prices == NULL)
			GL_THROW("Failure to allocate tier_prices array");

		cleared_load = (double *)gl_malloc(ArraySize*sizeof(double));

		if (cleared_load == NULL)
			GL_THROW("Failure to allocate cleared_load array");

		offPeakLoad = (double *)gl_malloc(FirstTierArraySize*sizeof(double));

		if (offPeakLoad == NULL)
			GL_THROW("Failure to allocate offPeakLoad array");

		peakLoad = (double *)gl_malloc(SecondTierArraySize*sizeof(double));

		if (peakLoad == NULL)
			GL_THROW("Failure to allocate peakLoad array");

		criticalPeakLoad = (double *)gl_malloc(ThirdTierArraySize*sizeof(double));

		if (criticalPeakLoad == NULL)
			GL_THROW("Failure to allocate criticalPeakLoad array");	

		//Link up to parent object
		enduseProperty = gl_get_property(parent,"base_power");
		if (enduseProperty == NULL)
			GL_THROW("Unable to map base power property");
		
		current_load_enduse = (enduse*)GETADDR(parent,enduseProperty);

		//Initialize the array locations
		ArrayIndex = 0;
		ThirdTierArrayIndex = 0;
		SecondTierArrayIndex = 0;
		FirstTierArrayIndex = 0;

		for(int32 i=0; i < ArraySize; i++){
			
			tier_prices[i] = 0;
			cleared_load[i] = 0;	
		}

		for(int32 i=0; i < FirstTierArraySize; i++){
			offPeakLoad[i] = 0;
		}
		
		for(int32 i=0; i < SecondTierArraySize; i++){
			peakLoad[i] = 0;
		}

		for(int32 i=0; i < ThirdTierArraySize; i++){
			criticalPeakLoad[i] = 0;
		}	
		
	}

	return 1;
}
Example #19
0
/* Object initialization is called once after all object have been created */
int office::init(OBJECT *parent)
{
	double oversize = 1.2; /* oversizing factor */
	update_control_setpoints();
	/* sets up default office parameters if none were passed:  floor height = 9ft; interior mass = 2000 Btu/degF;
	interior/exterior ua = 2 Btu/degF/h; floor area = 4000 sf*/

	if (zone.design.floor_area == 0)
		zone.design.floor_area = 10000;
	if (zone.design.floor_height == 0)
		zone.design.floor_height = 9;
	if (zone.design.interior_mass == 0)
		zone.design.interior_mass = 40000;
	if (zone.design.interior_ua == 0)
		zone.design.interior_ua = 1;
	if (zone.design.exterior_ua == 0)
		zone.design.exterior_ua = .375;

	if (zone.hvac.cooling.design_temperature == 0)
		zone.hvac.cooling.design_temperature = 93; // Pittsburgh, PA
	if (zone.hvac.heating.design_temperature == 0)  
		zone.hvac.heating.design_temperature = -6;  // Pittsburgh, PA
	

	if (zone.hvac.minimum_ach==0)
		zone.hvac.minimum_ach = 1.5;
	if (zone.control.economizer_cutin==0)
		zone.control.economizer_cutin=60;
	if (zone.control.auxiliary_cutin==0)
		zone.control.auxiliary_cutin=2;

	/* schedule */
	if (strcmp(zone.design.schedule,"")==0)
		strcpy(zone.design.schedule,"1-5 8-17"); /* default is unoccupied, MTWRF 8a-5p is occupied */
	occupancy_schedule(zone.design.schedule,occupied);

	/* automatic sizing of HVAC equipment */
	if (zone.hvac.heating.capacity==0)
		zone.hvac.heating.capacity = oversize*(zone.design.exterior_ua*(zone.control.heating_setpoint-zone.hvac.heating.design_temperature) /* envelope */
			- (zone.hvac.heating.design_temperature - zone.control.heating_setpoint) * (0.2402 * 0.0735 * zone.design.floor_height * zone.design.floor_area) * zone.hvac.minimum_ach); /* vent */
	if (zone.hvac.cooling.capacity==0)
		zone.hvac.cooling.capacity = oversize*(-zone.design.exterior_ua*(zone.hvac.cooling.design_temperature-zone.control.cooling_setpoint) /* envelope */
			- (zone.design.window_area[0]+zone.design.window_area[1]+zone.design.window_area[2]+zone.design.window_area[3]+zone.design.window_area[4]
				+zone.design.window_area[5]+zone.design.window_area[6]+zone.design.window_area[7]+zone.design.window_area[8])*100*3.412*zone.design.glazing_coeff /* solar */
			- (zone.hvac.cooling.design_temperature - zone.control.cooling_setpoint) * (0.2402 * 0.0735 * zone.design.floor_height * zone.design.floor_area) * zone.hvac.minimum_ach /* vent */
			- (zone.lights.capacity + zone.plugs.capacity)*3.412); /* lights and plugs */
	if (zone.hvac.cooling.cop==0)
		zone.hvac.cooling.cop=-3;
	if (zone.hvac.heating.cop==0)
		zone.hvac.heating.cop= 1.25;

	OBJECT *hdr = OBJECTHDR(this);

	// link to climate data
	static FINDLIST *climates = gl_find_objects(FL_NEW,FT_CLASS,SAME,"climate",FT_END);
	if (climates==NULL)
		gl_warning("office: no climate data found, using static data");
	else if (climates->hit_count>1)
		gl_warning("house: %d climates found, using first one defined", climates->hit_count);
	if (climates->hit_count>0)
	{
		OBJECT *obj = gl_find_next(climates,NULL);
		if (obj->rank<=hdr->rank)
			gl_set_dependent(obj,hdr);
		zone.current.pTemperature = (double*)GETADDR(obj,gl_get_property(obj,"temperature"));
		zone.current.pHumidity = (double*)GETADDR(obj,gl_get_property(obj,"humidity"));
		zone.current.pSolar = (double*)GETADDR(obj,gl_get_property(obj,"solar_flux"));
	}

	/* sanity check the initial values (no ticket) */
	struct {
		char *desc;
		bool test;
	} map[] = {
		/* list simple tests to be made on data (no ticket) */
		{"floor height is not valid", zone.design.floor_height<=0},
		{"interior mass is not valid", zone.design.interior_mass<=0},
		{"interior UA is not valid", zone.design.interior_ua<=0},
		{"exterior UA is not valid", zone.design.exterior_ua<=0},
		{"floor area is not valid",zone.design.floor_area<=0},
		{"control setpoint deadpoint is invalid", zone.control.setpoint_deadband<=0},
		{"heating and cooling setpoints conflict",TheatOn>=TcoolOff},
		{"cooling capacity is not negative", zone.hvac.cooling.capacity>=0},
		{"heating capacity is not positive", zone.hvac.heating.capacity<=0},
		{"cooling cop is not negative", zone.hvac.cooling.cop>=0},
		{"heating cop is not positive", zone.hvac.heating.cop<=0},
		{"minimum ach is not positive", zone.hvac.minimum_ach<=0},
		{"auxiliary cutin is not positive", zone.control.auxiliary_cutin<=0},
		{"economizer cutin is above cooling setpoint deadband", zone.control.economizer_cutin>=zone.control.cooling_setpoint-zone.control.setpoint_deadband},
	};
	int i;
	for (i=0; i<sizeof(map)/sizeof(map[0]); i++)
	{
		if (map[i].test)
			throw map[i].desc;
	}
	return 1; /* return 1 on success, 0 on failure */
}