Retrieving company name from HMService and/or HMAccessory object instance - accessory

I am using Home Kit Accessory simulator and I'd like to retrieve the company name of an accessory from an instance of HMService. However, when I add a breakpoint I cannot see any field related to the company name (I searched in both HMService and HMAccessory).
Any suggestion?

You can get name of Manufacturer from HMServiceTypeAccessoryInformation service, Service contains characteristic array in this there is HMCharacteristicTypeManufacturer characteristic.
You can use this to display name of company.
- (HMCharacteristic *)characteristicForAccessory:(HMAccessory *)accessoryValue{
HMAccessory *thisAccessory = accessoryValue;
HMService *service;
for (HMService *thisService in thisAccessory.services) {
if([thisService.serviceType isEqualToString:HMServiceTypeAccessoryInformation]) {
service = thisService;
}
}
HMCharacteristic *characteristic;
if (service) {
for (HMCharacteristic *charact in service.characteristics) {
if ([charact.characteristicType isEqualToString:HMCharacteristicTypeManufacturer]) {
characteristic = charact;
}
}
}
return characteristic;
}
Use Characteristic object's value property to get name of manufacturer.
Like characteristic.value

Take a look at Raeid Saqur's RSHomeKit framework:
You can get accessory by calling service.accessory. Then use:
+ (NSString *)getManufacturerNameForHMAccessory:(HMAccessory *)accessory;
+ (NSString *)getManufacturerNameForHMAccessory:(HMAccessory *)accessory {
if (!accessory) {
return nil;
}
HMCharacteristic *manufacturer = [HomeKitUtility getCharacteristicWithUUID:HMCharacteristicTypeManufacturer forAccessory:accessory];
if (manufacturer && manufacturer.value) {
return (NSString *)manufacturer.value;
}
return nil;
}

Related

How to retrieve a wall 's original geometry using Revit API?

In a project, I need to export a wall's original geometry to an IFC file. The so-called original geometry is the geometry of a wall without being cut by doors or windows hosted on the wall, without connections with roofs, floors, beams, columns, etc. The original geometry I wanted usually should be a shape like a box.
Unfortunately, there is no direct Revit API that gives me a wall's original geometry. The element.get_Geometry method returns the final geometry cut by doors, windows, and connected floors, roofs, etc.
One possible way to get a wall's original geometry is to rebuild geometry based on the wall's parameters myself, but my lazy method is to let Revit do the work. My method has five steps as follows:
Step 1: Start a Revit transaction.
Step 2: Before calling element.get_Geometry, temporarily delete the doors and windows hosted in the wall, as well as the roofs and floors connected with the wall, from the Revit document.
Step 3: Call document.Regenerate method to update the elements in the document. Of course, the wall's geometry should also be updated.
Step 4: Call element.get_Geometry to get the original geometry that I wanted.
Step 5: Rollback the transaction so that the Revit document remains unchanged.
The problem comes out in Step 2. Even if I had deleted the doors and windows, there are still openings in the returned geometry.
My question is, how to delete all elements related to a wall?
My Revit version is 2013. The .rvt file I used is rac_basic_sample_project.rvt shipped with Revit. The wall I want to export is the wall with id of 117698 or 117654.
My project is based on Revit IFC exporter source code.
The following is the code segment I used to get original geometry:
private GeometryElement GetOriginalWallGeometry2(Element element)
{
Document doc = element.Document;
GeometryElement geomElem = null;
//Step 1
using (Transaction t = new Transaction(doc))
{
//Step 2:
//delete wall joins
Autodesk.Revit.DB.Wall wall = element as Autodesk.Revit.DB.Wall;
//assert element is a wall
//the joined floors or roofs can be deleted as expected.
if (null != wall)
{
while (Autodesk.Revit.DB.WallUtils.IsWallJoinAllowedAtEnd(wall, 0))
{
Autodesk.Revit.DB.WallUtils.DisallowWallJoinAtEnd(wall, 0);
}
while (Autodesk.Revit.DB.WallUtils.IsWallJoinAllowedAtEnd(wall, 1))
{
Autodesk.Revit.DB.WallUtils.DisallowWallJoinAtEnd(wall, 1);
}
}
//The following code of deleting doors doesn't work as expected.
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> elementsList = collector.OfCategory(BuiltInCategory.OST_Doors).ToElements(); //here should be OST_Doors or others?
foreach (Element elem in elementsList)
{
try
{
doc.Delete(elem);
}
catch (System.Exception ex)
{
}
}
}
//The following code of deleting windows doesn't work as expected.
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> elementsList = collector.OfCategory(BuiltInCategory.OST_Windows).ToElements();//here should be OST_Windows or others?
foreach (Element elem in elementsList)
{
try
{
doc.Delete(elem);
}
catch (System.Exception ex)
{
}
}
}
//The following code also doesn't work as expected.
Autodesk.Revit.DB.HostObject hostObj = element as Autodesk.Revit.DB.HostObject;
if (hostObj != null)
{
IList<ElementId> idlist = hostObj.FindInserts(true, true, true, true);
foreach (ElementId id in idlist)
{
try
{
doc.Delete(id);
}
catch (System.Exception ex)
{
}
}
}
//Floors can be deteled as expected.
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> linkList = collector.OfCategory(BuiltInCategory.OST_Floors).ToElements();
foreach (Element elelink in linkList)
{
try
{
doc.Delete(elelink);
}
catch (System.Exception ex)
{
}
}
}
//Roofs can be deteled as expected.
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> linkList = collector.OfCategory(BuiltInCategory.OST_Roofs).ToElements();
foreach (Element elelink in linkList)
{
try
{
doc.Delete(elelink);
}
catch (System.Exception ex)
{
}
}
}
//Step 3
doc.Regenerate();
//Step 4
Options options;
View ownerView = element.Document.GetElement(element.OwnerViewId) as View;
if (ownerView == null)
{
options = GeometryUtil.GetIFCExportGeometryOptions();
}
else
{
options = new Options();
options.View = ownerView;
}
geomElem = element.get_Geometry(options);
//Step 5
FailureHandlingOptions failureOptions = t.GetFailureHandlingOptions();
failureOptions.SetClearAfterRollback(true);
failureOptions.SetDelayedMiniWarnings(true);
t.SetFailureHandlingOptions(failureOptions);
try
{
t.RollBack();
}
catch (System.Exception ex)
{
}
}
return geomElem;
}
I use the following method to retrieve elements of a particular category.
/// <summary>
/// Get all elements of the specified type that fall into the specified category
/// <para>The specified type must derive from Element, or you can use Element but you get everything :)</para>
/// </summary>
/// <typeparam name="T">The type of element to get</typeparam>
/// <param name="builtInCategory">The BuiltinCategory to discriminate the element set</param>
/// <returns>The collection of elements that match the type and specified categry</returns>
public IEnumerable<T> GetElements<T>(BuiltInCategory builtInCategory) where T : Element
{
FilteredElementCollector collector = new FilteredElementCollector(Document);
// Seems you must be a subclass of element to use the OfClass method
if (typeof(T) != typeof(Element))
collector.OfClass(typeof(T));
collector.OfCategory(builtInCategory);
return collector.Cast<T>();
}
If you are trying to get doors and windows then it would be used as such
var doors = GetElements<FamilyInstance>(BuiltInCategory.OST_DOORS);
var windows = GetElements<FamilyInstance>(BuiltInCategory.OST_WINDOWS);
That presumes that the openings you are looking for are doors or windows.
If you are looking for void extrusions, etc, within the wall or other types of openings then you will need to be more specific in your question.
As a more complex version of the function shown above I use the following method when I wish to also apply a filter against the elements being retrieved.
/// <summary>
/// Get the collection of elements of the specified type that are within the provided category that also pass the filter.
/// <para>The specified type must derive from Element, or you can use Element but you get everything :)</para>
/// </summary>
/// <typeparam name="T">The type of element to get</typeparam>
/// <param name="builtInCategory">The BuiltinCategory to discriminate the element set</param>
/// <param name="filter">The filter to check the element against</param>
/// <returns>The collection of elements of the specified type and specified category that pass the filter</returns>
public IEnumerable<T> GetElements<T>(BuiltInCategory builtInCategory, ElementFilter filter) where T : Element
{
FilteredElementCollector collector = new FilteredElementCollector(Document);
// Seems you must be a subclass of element to use the OfClass method
if (typeof(T) != typeof(Element))
collector.OfClass(typeof(T));
collector.OfCategory(builtInCategory);
collector.WherePasses(filter);
return collector.Cast<T>();
}
The advantage of using the method approach defined above is that it will isolate your code from Revit API changes in the future rather than using the same code blocks repeatedly throughout your code base.
If you want to retrieve Windows, Doors and any other opening on the wall, this is the right code:
var ids = (yourCurrentWallElement as Wall).FindInserts(true, true, true, true);
foreach (ElementId id in ids)
{
var el = doc.GetElement(id);
Debug.WriteLine(" Id: " + el.Id);
Debug.WriteLine(" Type: " + el.GetType().Name);
Debug.WriteLine(" Category: " + el.Category.Name);
Debug.WriteLine(" Type: " + el.GetType().Name);
if (el is FamilyInstance)
{
var fi = el as FamilyInstance;
if (fi != null)
Debug.WriteLine(" Symbol Name: " + fi.Symbol.Name);
}
}
More info on the FindInserts -> http://revitapisearch.com/html/58990230-38cb-3af7-fd25-96ed3215a43d.htm
Other example -> http://spiderinnet.typepad.com/blog/2012/04/get-wall-inserts-using-the-revit-wallfindinserts-net-api.html

Creating a unattached Entity Framework DbContext entity

So I'm working on an app that will select data from one database and update an identical database based on information contained in a 'Publication' Table in the Authoring database. I need to get a single object that is not connected to the 'Authoring' context so I can add it to my 'Delivery' context.
Currently I am using
object authoringRecordVersion = PublishingFactory.AuthoringContext.Set(recordType.Entity.GetType()).Find(record.RecordId);
object deliveryRecordVersion = PublishingFactory.DeliveryContext.Set(recordType.Entity.GetType()).Find(record.RecordId));
to return my records. Then if the 'deliveryRecordVersion' is null, I need to do an Insert of 'authoringRecordVersion' into 'PublishingFactory.DeliveryContext'. However, that object is already connected to the 'PublishingFactory.AuthoringContext' so it won't allow the Add() method to be called on the 'PublishingFactory.DeliveryContext'.
I have access to PublishingFactory.AuthoringContext.Set(recordType.Entity.GetType()).AsNoTracking()
but there is no way to get at the specific record I need from here.
Any suggestions?
UPDATE:
I believe I found the solution. It didn't work the first time because I was referencing the wrong object on when setting .State = EntityState.Detached;
here is the full corrected method that works as expected
private void PushToDelivery(IEnumerable<Mkl.WebTeam.UWManual.Model.Publication> recordsToPublish)
{
string recordEntity = string.Empty;
DbEntityEntry recordType = null;
// Loop through recordsToPublish and see if the record exists in Delivery. If so then 'Update' the record
// else 'Add' the record.
foreach (var record in recordsToPublish)
{
if (recordEntity != record.Entity)
{
recordType = PublishingFactory.DeliveryContext.Entry(ObjectExt.GetEntityOfType(record.Entity));
}
if (recordType == null)
{
continue;
////throw new NullReferenceException(
//// string.Format("Couldn't identify the object type stored in record.Entity : {0}", record.Entity));
}
// get the record from the Authoring context from the appropriate type table
object authoringRecordVersion = PublishingFactory.AuthoringContext.Set(recordType.Entity.GetType()).Find(record.RecordId);
// get the record from the Delivery context from the appropriate type table
object deliveryRecordVersion = PublishingFactory.DeliveryContext.Set(recordType.Entity.GetType()).Find(record.RecordId);
// somthing happened and no records were found meeting the Id and Type from the Publication table in the
// authoring table
if (authoringRecordVersion == null)
{
continue;
}
if (deliveryRecordVersion != null)
{
// update record
PublishingFactory.DeliveryContext.Entry(deliveryRecordVersion).CurrentValues.SetValues(authoringRecordVersion);
PublishingFactory.DeliveryContext.Entry(deliveryRecordVersion).State = EntityState.Modified;
PublishingFactory.DeliveryContext.SaveChanges();
}
else
{
// insert new record
PublishingFactory.AuthoringContext.Entry(authoringRecordVersion).State = EntityState.Detached;
PublishingFactory.DeliveryContext.Entry(authoringRecordVersion).State = EntityState.Added;
PublishingFactory.DeliveryContext.SaveChanges();
}
recordEntity = record.Entity;
}
}
As you say in your comment the reason why you can't use .Single(a => a.ID == record.RecordId) is that the ID property is not known at design time. So what you can do is get the entity by the Find method and then detach it from the context:
PublishingFactory.AuthoringContext
.Entry(authoringRecordVersion).State = EntityState.Detached;

Reading Contact List in Micromax Q50

I am using the following code to read Contact List in Micromax Device.
But without any success.
try {
PIM t_pim = PIM.getInstance();
String[] namesOfContactLists = t_pim.listPIMLists(PIM.CONTACT_LIST);
PIMList t_pimlist = t_pim.openPIMList(PIM.CONTACT_LIST, PIM.READ_ONLY, namesOfContactLists[0]);//namesOfContactLists[0] is the Phone List.
Enumeration t_enumeration = t_pimlist.items();
boolean isFormattedNameSupported = t_pimlist.isSupportedField(Contact.FORMATTED_NAME);
while (t_enumeration.hasMoreElements()) {
String t_contactName = "";
Contact t_contact = (Contact) t_enumeration.nextElement();
if (isFormattedNameSupported) {
if (t_contact.countValues(Contact.FORMATTED_NAME) > 0) {
t_contactName = t_contact.getString(Contact.FORMATTED_NAME, 0);//Throws UnsupportedFieldException
}
}
}
} catch (PIMException ex) {
ex.printStackTrace();
}
Other options like Contact.NAME, Contact.NAME_GIVEN, Contact.NAME_FAMILY, Contact.NAME_OTHER, Contact.NAME_PREFIX, Contact.NAME_SUFFIX, Contact.NICKNAME also throw the same UnsupportedFieldException.
This code works fine on Nokia and Sony Ericsson devices. But fails on Micromax.
When you say "without any success", what do you mean? What actually happens? If you mean that FORMATTED_NAME is an unsupported field for Contact, then these fields are optional. Use PIMList.getSupportedFields() to figure out which fields you can read on each platform.

Get item’s metadata with Entity Framework?

I'm working with Sharepoint 2010.
I need to know the date of creation/edition and the author/editor of items in my sharepoint's Lists, but I didn't find a solution to map these columns with Entity Framework.
I tried this kind of code :
[Microsoft.SharePoint.Linq.ColumnAttribute(Name = "tp_author", Storage = "_author", ReadOnly = true, FieldType = "User")]
public SPUser Author
{
get
{
return this._author;
}
set
{
if (!value.Equals(this._author))
{
this.OnPropertyChanging("Author", this._author);
this._author = value;
this.OnPropertyChanged("Author");
}
}
}
But with that code, Sharepoint give me this error:
Invalid transfer type Microsoft.SharePoint.SPUser
I also tried with other types for _author, but it doesn't change anything.
Is there a way to make this mapping?
SPMetal generates the following code for a user field
[Microsoft.SharePoint.Linq.ColumnAttribute(Name="AssignedTo", Storage="_assignedToId", FieldType="User", IsLookupId=true)]
public System.Nullable<int> AssignedToId {
get {
return this._assignedToId;
}
set {
if ((value != this._assignedToId)) {
this.OnPropertyChanging("AssignedToId", this._assignedToId);
this._assignedToId = value;
this.OnPropertyChanged("AssignedToId");
}
}
}
[Microsoft.SharePoint.Linq.ColumnAttribute(Name="AssignedTo", Storage="_assignedTo", ReadOnly=true, FieldType="User", IsLookupValue=true)]
public string AssignedTo {
get {
return this._assignedTo;
}
set {
if ((value != this._assignedTo)) {
this.OnPropertyChanging("AssignedTo", this._assignedTo);
this._assignedTo = value;
this.OnPropertyChanged("AssignedTo");
}
}
}

Check Active directory Group membership

How do i go about iterating a group to find out if a given user is a member of a group?
I know i can use IsInRole on WindowsPrincipal object but for some reason it don't always work for me, it doesn't error out or throw exception but just return false.
i have put together following code from web, can some help me improve it in terms of reliability, it hasn't gave any wrong result in 3 weeks of testing.
Side notes: 1: I don't have access to AD username and password hence using GC. 2: Groups can be created in any domain but with in same forest. 3: Group can have users from various domains as well as groups.
thanks
KA
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
static extern int CheckTokenMembership(int TokenHandle, byte[] PSID, out bool IsMember);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
static extern bool IsValidSid(byte[] PSID);
private bool Authenticate(XmlNodeList XmlNodeGroups)
{
bool result = false;
try
{
Dictionary<string, List<string>> Groups = GetGroups(XmlNodeGroups);
//search global catalog and get SID of the group
Byte[] sid = null;
foreach (string groupName in Groups.Keys)
{
using (DirectoryEntry entry = new DirectoryEntry("GC:"))
{
IEnumerator ie = entry.Children.GetEnumerator();
ie.MoveNext();
using (DirectorySearcher ds = new DirectorySearcher((DirectoryEntry)ie.Current))
{
ds.Filter = string.Format("(&(|(sAMAccountName={0}))(objectClass=group))", groupName);
using (SearchResultCollection resColl = ds.FindAll())
{
if (resColl.Count > 0)
{
ResultPropertyCollection resultPropColl = resColl[0].Properties;
sid = (byte[])resultPropColl["objectsid"][0];
if (sid == null || !IsValidSid(sid))
{
// log message and continue to next group continue;
}
}
else
{
// log message and continue to next group continue;
}
}
bool bIsMember = false;
if (CheckTokenMembership(0, sid, out bIsMember) == 0)
{
// log message and initiate fall back....... use Legacy
result = CheckMemberOf(XmlNodeGroups, _CurrentIdentity);
break;
}
else
{
result = bIsMember ? true : false;
if (result)
{
// debug message break;
}
else
{
// debug message
}
}
}
}
}
}
catch (Exception ex)
{
// log exception message and initiate fall back....... use Legacy
result = CheckMemberOf(XmlNodeGroups, _CurrentIdentity);
}
return result;
}</code>
Are you on .NET 3.5 ? If so, check out the MSDN magazine article Managing Directory Security Principals in the .NET Framework 3.5. It shows just how much easier things have become when it comes to users and groups in AD.
As for your requirement - you could
find the group in question
enumerate all its members
find if your given user is a member in that group
and all this can be done quite easily with the help of the System.DirectoryServices.AccountManagement namespace:
// establish a context - define a domain (NetBIOS style name),
// or use the current one, when not specifying a specific domain
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find the group in question
GroupPrincipal theGroup = GroupPrincipal.FindByIdentity(ctx, "nameOfGroup");
// recursively enumerate the members of the group; making the search
// recursive will also enumerate the members of any nested groups
PrincipalSearchResult<Principal> result = theGroup.GetMembers(true);
// find the user in the list of group members
UserPrincipal user = (result.FirstOrDefault(p => p.DisplayName == "Some Name") as UserPrincipal);
// if found --> user is member of this group, either directly or recursively
if(user != null)
{
// do something with the user
}
I tried to use your code snippet above for the 3.5 framework and this line my compiler says it's incorrect:
// find the user in the list of group members
UserPrincipal user = (result.FirstOrDefault(p => p.DisplayName == adUser) as UserPrincipal);
Specifically the result.FirstOfDefault, it says that's not a valid option.
Thanks!

Resources