Repository: NREL/OpenStudio (language: python)

Issue:
Space load-based actuator for spaces are named based on thermal zone name
Issue overview
--------------
The actuated component unique name of EMS:Actuator objects in EnergyPlus is determined by OS during the forward translation process. The name appears to be based on the zone name and load object (Lights in the example below) name, even for spaces. However, when spaces are used in a model, EnergyPlus expected the name of the actuator to refer to the space name, not the zone name

## Current Behavior
The code snippet below creates the following actuator ....
```
EnergyManagementSystem:Actuator,
    Energy_Management_System_Actuator_1,  !- Name
    Thermal Zone 1 Lights 1, !- Actuated Component Unique Name
    Lights,                  !- Actuated Component Type
    Electricity Rate;        !- Actuated Component Control Type
```

## Expected Behavior
... but it should be:
```
EnergyManagementSystem:Actuator,
    Energy_Management_System_Actuator_1,  !- Name
    Space 1 Lights 1, !- Actuated Component Unique Name
    Lights,                  !- Actuated Component Type
    Electricity Rate;        !- Actuated Component Control Type
```

## Steps to Reproduce

```ruby
require 'openstudio'
include OpenStudio::Model

model = Model.new()
spaceType1 = SpaceType.new(model)
space1 = Space.new(model)
tz1 = ThermalZone.new(model)

space1.setThermalZone(tz1)
space1.setSpaceType(spaceType1)

spaceType1.setLightingPowerPerFloorArea(0.5)

light = space1.spaceType.get.lights[0]

actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light, 'Lights', 'Electricity Rate', space1)

ft = OpenStudio::EnergyPlus::ForwardTranslator.new
w = ft.translateModel(model)
puts w.getObjectsByType("EnergyManagementSystem:Actuator")
```

```
EnergyManagementSystem:Actuator,
  Energy_Management_System_Actuator_1,    !- Name
  Thermal Zone 1 Lights 1,                !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

## Possible Solution
Do not use the thermal zone name by default [here](https://github.com/NREL/OpenStudio/blob/1f8353e48d5bbb441b5d1b96ac8b3d877f5df457/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp#L122-L124).

### Environment

Some additional details about your environment for this issue (if relevant):
 - Platform: Windows
 - Version of OpenStudio: Tested in 3.5.1

### Context
Affects https://github.com/NREL/openstudio-standards/issues/1395.

Space load-based actuator for spaces are named based on thermal zone name
Issue overview
--------------
The actuated component unique name of EMS:Actuator objects in EnergyPlus is determined by OS during the forward translation process. The name appears to be based on the zone name and load object (Lights in the example below) name, even for spaces. However, when spaces are used in a model, EnergyPlus expected the name of the actuator to refer to the space name, not the zone name

## Current Behavior
The code snippet below creates the following actuator ....
```
EnergyManagementSystem:Actuator,
    Energy_Management_System_Actuator_1,  !- Name
    Thermal Zone 1 Lights 1, !- Actuated Component Unique Name
    Lights,                  !- Actuated Component Type
    Electricity Rate;        !- Actuated Component Control Type
```

## Expected Behavior
... but it should be:
```
EnergyManagementSystem:Actuator,
    Energy_Management_System_Actuator_1,  !- Name
    Space 1 Lights 1, !- Actuated Component Unique Name
    Lights,                  !- Actuated Component Type
    Electricity Rate;        !- Actuated Component Control Type
```

## Steps to Reproduce

```ruby
require 'openstudio'
include OpenStudio::Model

model = Model.new()
spaceType1 = SpaceType.new(model)
space1 = Space.new(model)
tz1 = ThermalZone.new(model)

space1.setThermalZone(tz1)
space1.setSpaceType(spaceType1)

spaceType1.setLightingPowerPerFloorArea(0.5)

light = space1.spaceType.get.lights[0]

actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light, 'Lights', 'Electricity Rate', space1)

ft = OpenStudio::EnergyPlus::ForwardTranslator.new
w = ft.translateModel(model)
puts w.getObjectsByType("EnergyManagementSystem:Actuator")
```

```
EnergyManagementSystem:Actuator,
  Energy_Management_System_Actuator_1,    !- Name
  Thermal Zone 1 Lights 1,                !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

## Possible Solution
Do not use the thermal zone name by default [here](https://github.com/NREL/OpenStudio/blob/1f8353e48d5bbb441b5d1b96ac8b3d877f5df457/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp#L122-L124).

### Environment

Some additional details about your environment for this issue (if relevant):
 - Platform: Windows
 - Version of OpenStudio: Tested in 3.5.1

### Context
Affects https://github.com/NREL/openstudio-standards/issues/1395.

Space load-based actuator for spaces are named based on thermal zone name
Issue overview
--------------
The actuated component unique name of EMS:Actuator objects in EnergyPlus is determined by OS during the forward translation process. The name appears to be based on the zone name and load object (Lights in the example below) name, even for spaces. However, when spaces are used in a model, EnergyPlus expected the name of the actuator to refer to the space name, not the zone name

## Current Behavior
The code snippet below creates the following actuator ....
```
EnergyManagementSystem:Actuator,
    Energy_Management_System_Actuator_1,  !- Name
    Thermal Zone 1 Lights 1, !- Actuated Component Unique Name
    Lights,                  !- Actuated Component Type
    Electricity Rate;        !- Actuated Component Control Type
```

## Expected Behavior
... but it should be:
```
EnergyManagementSystem:Actuator,
    Energy_Management_System_Actuator_1,  !- Name
    Space 1 Lights 1, !- Actuated Component Unique Name
    Lights,                  !- Actuated Component Type
    Electricity Rate;        !- Actuated Component Control Type
```

## Steps to Reproduce

```ruby
require 'openstudio'
include OpenStudio::Model

model = Model.new()
spaceType1 = SpaceType.new(model)
space1 = Space.new(model)
tz1 = ThermalZone.new(model)

space1.setThermalZone(tz1)
space1.setSpaceType(spaceType1)

spaceType1.setLightingPowerPerFloorArea(0.5)

light = space1.spaceType.get.lights[0]

actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light, 'Lights', 'Electricity Rate', space1)

ft = OpenStudio::EnergyPlus::ForwardTranslator.new
w = ft.translateModel(model)
puts w.getObjectsByType("EnergyManagementSystem:Actuator")
```

```
EnergyManagementSystem:Actuator,
  Energy_Management_System_Actuator_1,    !- Name
  Thermal Zone 1 Lights 1,                !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

## Possible Solution
Do not use the thermal zone name by default [here](https://github.com/NREL/OpenStudio/blob/1f8353e48d5bbb441b5d1b96ac8b3d877f5df457/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp#L122-L124).

### Environment

Some additional details about your environment for this issue (if relevant):
 - Platform: Windows
 - Version of OpenStudio: Tested in 3.5.1

### Context
Affects https://github.com/NREL/openstudio-standards/issues/1395.



Discussion / hints:
Should use `getSpaceLoadParent`? https://github.com/NREL/OpenStudio/blob/1f8353e48d5bbb441b5d1b96ac8b3d877f5df457/src/energyplus/ForwardTranslator.cpp#L228
This was tricky back in the day because OS didnt use ZoneLists, but E+ did, etc.  The constructors were built with the following

https://github.com/NREL/OpenStudio/blob/99e001d02545ad4c65938f49b411179418662f9f/src/model/EnergyManagementSystemActuator.hpp#L62-L72

I would look at the constructor first to make sure the assumptions are still valid, given the space changes in E+, etc
@lymereJ Note that in your "Steps to Reproduce" section above, the `light` variable is unused. Should it be passed into the first position of `EnergyManagementSystemActuator.new(...)`?
yeah, i think the light object goes first, and the TZ or space goes last.
https://github.com/NREL/OpenStudio/blob/develop/src/model/test/EnergyManagementSystemActuator_GTest.cpp#L215
https://github.com/NREL/OpenStudio/blob/develop/src/model/test/EnergyManagementSystemActuator_GTest.cpp#L258
@joseph-robertson - You're correct, may bad. The code that I have in "Steps to Reproduce" generates the following actuator (incorrect as well), not the one that's in "Current Behavior". Not sure why I put `space1` instead of `light`.

```
EnergyManagementSystem:Actuator,
  Energy_Management_System_Actuator_1,    !- Name
  Space 1,                                !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

I'll correct that line in "Step to Reproduce". Thanks!
@lymereJ is an option for you now to just disable the space feature when forward translating?
> This was tricky back in the day because OS didnt use ZoneLists, but E+ did, etc. The constructors were built with the following
> 
> https://github.com/NREL/OpenStudio/blob/99e001d02545ad4c65938f49b411179418662f9f/src/model/EnergyManagementSystemActuator.hpp#L62-L72

Shouldn't these take in a SpaceLoadInstance instead of a ModelObject given the comment? I could see it going really wrong...
> @lymereJ is an option for you now to just disable the space feature when forward translating?

@jmarrec, I believe that we don't want to do that, this is for OpenStudio-Standards. I'll let @mdahlhausen confirm.
> > @lymereJ is an option for you now to just disable the space feature when forward translating?
> 
> @jmarrec, I believe that we don't want to do that, this is for OpenStudio-Standards. I'll let @mdahlhausen confirm.

yeah, that's not a workable solution.  People are build models using openstudio-standards, often in third-party software. I don't want to require third-party developers to have to disable the space feature when forward translating. Especially for end-users who might not know how to disable it. 

OK. I'm asking because this is marked as blocker, we're close to release date, and we have the existing API to retain.
I'll try to figure something out in the next couple of days that aims to support this without breaking api, I'll likely ask for thoughts/decisions as I dig down.
not sure if this helps with the debugging, but here is a measure that reproduces the EMS Demand Management example#9 and uses the Actuator on the lights object.
https://github.com/NREL/OpenStudio-EMS-Measures/blob/master/Measures/m_9_example_9_demand_management/measure.rb#L301

I'm going to try to see if there is a workaround in openstudio-standards.
i just checked and this does work in OS <=3.2 but not in OS 3.5.1

require 'openstudio'
model = OpenStudio::Model.exampleModel()
spaceType1 = model.getSpaceTypes()[0]
space1 = model.getSpaces()[0]
tz1 = model.getThermalZones()[0]

light = space1.spaceType.get.lights[0]
actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light, 'Lights', 'Electricity Rate', space1)

ft = OpenStudio::EnergyPlus::ForwardTranslator.new
w = ft.translateModel(model)

my bet it has something to do with no more ZoneLists or the new spaces

![image](https://user-images.githubusercontent.com/2235296/225111019-2ac827ca-3591-401e-b02e-c6943a98d69c.png)

looks like the actuators changed to use Spaces instead of Thermal Zones according to the .EDD

![image](https://user-images.githubusercontent.com/2235296/225112539-043cc941-c94d-441e-91e5-893a1b62d45b.png)

my guess is to use the space.name https://github.com/NREL/OpenStudio/blob/develop/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp#L124
instead of the thermal zone name

and something similiar here https://github.com/NREL/OpenStudio/blob/develop/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp#L105 
for getting the space name from the spacetype.

Some more context: 
Running test_small_office.rb for 90.1-2016 and ASHRAE 169-2013-5A

In OS 3.2.1:

```
OS:EnergyManagementSystem:Sensor,
  {9d59be4e-d960-47c1-aa96-6783eb166770}, !- Handle
  Core_ZNZN_LSr,                          !- Name
  Core_ZN ZN,                             !- Output Variable or Output Meter Index Key Name
  Zone Lights Electricity Rate;           !- Output Variable or Output Meter Name

OS:EnergyManagementSystem:InternalVariable,
  {496b4e8d-6dbc-49c2-8fd6-f0a0292d0d74}, !- Handle
  Core_ZNZN_Area,                         !- Name
  Core_ZN ZN,                             !- Internal Data Index Key Name
  Zone Floor Area;                        !- Internal Data Type

OS:EnergyManagementSystem:Actuator,
  {4936ef85-4857-41ae-b64f-5308c174d49f}, !- Handle
  Core_ZNZN_Light1_Actuator,              !- Name
  {a5e82b87-ce0f-4588-9715-85b90f56135a}, !- Actuated Component Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type

OS:EnergyManagementSystem:Actuator,
  {69231cf4-fc89-48f6-a304-29cadfe9f63c}, !- Handle
  Perimeter_ZN_1ZN_Light1_Actuator,       !- Name
  {a5e82b87-ce0f-4588-9715-85b90f56135a}, !- Actuated Component Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

actuated component is:

```
OS:Lights,
  {a5e82b87-ce0f-4588-9715-85b90f56135a}, !- Handle
  Office WholeBuilding - Sm Office Lights, !- Name
  {72e4e8c6-2310-41ff-856b-20a2cebb0674}, !- Lights Definition Name
  {629a271e-7460-4c51-87d3-d2d3125cfac1}, !- Space or SpaceType Name
  ,                                       !- Schedule Name
  1,                                      !- Fraction Replaceable
  ,                                       !- Multiplier
  General;                                !- End-Use Subcategory
```

which is used by this space type object:

```
OS:SpaceType,
  {629a271e-7460-4c51-87d3-d2d3125cfac1}, !- Handle
  Office WholeBuilding - Sm Office,       !- Name
  ,                                       !- Default Construction Set Name
  {09f83373-2543-4efe-ad90-7facebecbcbb}, !- Default Schedule Set Name
  {c9f3a3a1-7407-4eab-bb64-27cdfc8e7a35}, !- Group Rendering Name
  {58b7ecf6-9d4d-4d56-95e8-b61a0fed9557}, !- Design Specification Outdoor Air Object Name
  ,                                       !- Standards Template
  Office,                                 !- Standards Building Type
  WholeBuilding - Sm Office;              !- Standards Space Type
```

The test passes but generates this warning from the forward translator:
`[openstudio.energyplus.ForwardTranslator] <0> Actuator 'Core_ZNZN_Light1_Actuator' references a SpaceLoad 'Office WholeBuilding - Sm Office Lights' attached to SpaceType 'Office WholeBuilding - Sm Office', with multiple spaces. Check your EMS programs to make sure your actuators are correct.
`

What appears in the .idf:

```
EnergyManagementSystem:Actuator,
  Core_ZNZN_Light1_Actuator,              !- Name
  Core_ZN ZN Office WholeBuilding - Sm Office Lights, !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type

EnergyManagementSystem:Actuator,
  Perimeter_ZN_1ZN_Light1_Actuator,       !- Name
  Core_ZN ZN Office WholeBuilding - Sm Office Lights, !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

All of the actuators point to the same shared lights object. That's a bug.

And it errors out now in OS 3.5.1:
```
   ** Severe  ** Invalid Actuated Component Unique Name =CORE_ZN ZN OFFICE WHOLEBUILDING - SM OFFICE LIGHTS
   **   ~~~   ** Entered in EnergyManagementSystem:Actuator=CORE_ZNZN_LIGHT1_ACTUATOR
```

It seems there are two issues here:
1) There is a bug in openstudio-standards; the lights object needs to be broken out by zone or space before applying EMS code
2) The forward translator simply can't handle shared space/zone lights objects required by EMS.  Ideally, it would take a shared space type resource like the lights object and make zone individually for each space if shared by EMS.  Or we can say you can't use shared space type resources with EMS. 

I think I can fix openstudio-standards by creating individual space light objects in OS 3.5.1, which means this issue is no longer a blocker. @lymereJ correct me here if you don't think that's possible.
@lymereJ @jmarrec Update: I've got a decent workaround [implemented in openstudio-standards](https://github.com/NREL/openstudio-standards/pull/1447).  I clone the space type lights object to each individual space.  Works with both OSv3.2.1 and OSv3.5.1.

Given the workaround, this issue is no longer an OpenStudio blocker for openstudio-standards.
Should use `getSpaceLoadParent`? https://github.com/NREL/OpenStudio/blob/1f8353e48d5bbb441b5d1b96ac8b3d877f5df457/src/energyplus/ForwardTranslator.cpp#L228
This was tricky back in the day because OS didnt use ZoneLists, but E+ did, etc.  The constructors were built with the following

https://github.com/NREL/OpenStudio/blob/99e001d02545ad4c65938f49b411179418662f9f/src/model/EnergyManagementSystemActuator.hpp#L62-L72

I would look at the constructor first to make sure the assumptions are still valid, given the space changes in E+, etc
@lymereJ Note that in your "Steps to Reproduce" section above, the `light` variable is unused. Should it be passed into the first position of `EnergyManagementSystemActuator.new(...)`?
yeah, i think the light object goes first, and the TZ or space goes last.
https://github.com/NREL/OpenStudio/blob/develop/src/model/test/EnergyManagementSystemActuator_GTest.cpp#L215
https://github.com/NREL/OpenStudio/blob/develop/src/model/test/EnergyManagementSystemActuator_GTest.cpp#L258
@joseph-robertson - You're correct, may bad. The code that I have in "Steps to Reproduce" generates the following actuator (incorrect as well), not the one that's in "Current Behavior". Not sure why I put `space1` instead of `light`.

```
EnergyManagementSystem:Actuator,
  Energy_Management_System_Actuator_1,    !- Name
  Space 1,                                !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

I'll correct that line in "Step to Reproduce". Thanks!
@lymereJ is an option for you now to just disable the space feature when forward translating?
> This was tricky back in the day because OS didnt use ZoneLists, but E+ did, etc. The constructors were built with the following
> 
> https://github.com/NREL/OpenStudio/blob/99e001d02545ad4c65938f49b411179418662f9f/src/model/EnergyManagementSystemActuator.hpp#L62-L72

Shouldn't these take in a SpaceLoadInstance instead of a ModelObject given the comment? I could see it going really wrong...
> @lymereJ is an option for you now to just disable the space feature when forward translating?

@jmarrec, I believe that we don't want to do that, this is for OpenStudio-Standards. I'll let @mdahlhausen confirm.
> > @lymereJ is an option for you now to just disable the space feature when forward translating?
> 
> @jmarrec, I believe that we don't want to do that, this is for OpenStudio-Standards. I'll let @mdahlhausen confirm.

yeah, that's not a workable solution.  People are build models using openstudio-standards, often in third-party software. I don't want to require third-party developers to have to disable the space feature when forward translating. Especially for end-users who might not know how to disable it. 

OK. I'm asking because this is marked as blocker, we're close to release date, and we have the existing API to retain.
I'll try to figure something out in the next couple of days that aims to support this without breaking api, I'll likely ask for thoughts/decisions as I dig down.
not sure if this helps with the debugging, but here is a measure that reproduces the EMS Demand Management example#9 and uses the Actuator on the lights object.
https://github.com/NREL/OpenStudio-EMS-Measures/blob/master/Measures/m_9_example_9_demand_management/measure.rb#L301

I'm going to try to see if there is a workaround in openstudio-standards.
i just checked and this does work in OS <=3.2 but not in OS 3.5.1

require 'openstudio'
model = OpenStudio::Model.exampleModel()
spaceType1 = model.getSpaceTypes()[0]
space1 = model.getSpaces()[0]
tz1 = model.getThermalZones()[0]

light = space1.spaceType.get.lights[0]
actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light, 'Lights', 'Electricity Rate', space1)

ft = OpenStudio::EnergyPlus::ForwardTranslator.new
w = ft.translateModel(model)

my bet it has something to do with no more ZoneLists or the new spaces

![image](https://user-images.githubusercontent.com/2235296/225111019-2ac827ca-3591-401e-b02e-c6943a98d69c.png)

looks like the actuators changed to use Spaces instead of Thermal Zones according to the .EDD

![image](https://user-images.githubusercontent.com/2235296/225112539-043cc941-c94d-441e-91e5-893a1b62d45b.png)

my guess is to use the space.name https://github.com/NREL/OpenStudio/blob/develop/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp#L124
instead of the thermal zone name

and something similiar here https://github.com/NREL/OpenStudio/blob/develop/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp#L105 
for getting the space name from the spacetype.

Some more context: 
Running test_small_office.rb for 90.1-2016 and ASHRAE 169-2013-5A

In OS 3.2.1:

```
OS:EnergyManagementSystem:Sensor,
  {9d59be4e-d960-47c1-aa96-6783eb166770}, !- Handle
  Core_ZNZN_LSr,                          !- Name
  Core_ZN ZN,                             !- Output Variable or Output Meter Index Key Name
  Zone Lights Electricity Rate;           !- Output Variable or Output Meter Name

OS:EnergyManagementSystem:InternalVariable,
  {496b4e8d-6dbc-49c2-8fd6-f0a0292d0d74}, !- Handle
  Core_ZNZN_Area,                         !- Name
  Core_ZN ZN,                             !- Internal Data Index Key Name
  Zone Floor Area;                        !- Internal Data Type

OS:EnergyManagementSystem:Actuator,
  {4936ef85-4857-41ae-b64f-5308c174d49f}, !- Handle
  Core_ZNZN_Light1_Actuator,              !- Name
  {a5e82b87-ce0f-4588-9715-85b90f56135a}, !- Actuated Component Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type

OS:EnergyManagementSystem:Actuator,
  {69231cf4-fc89-48f6-a304-29cadfe9f63c}, !- Handle
  Perimeter_ZN_1ZN_Light1_Actuator,       !- Name
  {a5e82b87-ce0f-4588-9715-85b90f56135a}, !- Actuated Component Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

actuated component is:

```
OS:Lights,
  {a5e82b87-ce0f-4588-9715-85b90f56135a}, !- Handle
  Office WholeBuilding - Sm Office Lights, !- Name
  {72e4e8c6-2310-41ff-856b-20a2cebb0674}, !- Lights Definition Name
  {629a271e-7460-4c51-87d3-d2d3125cfac1}, !- Space or SpaceType Name
  ,                                       !- Schedule Name
  1,                                      !- Fraction Replaceable
  ,                                       !- Multiplier
  General;                                !- End-Use Subcategory
```

which is used by this space type object:

```
OS:SpaceType,
  {629a271e-7460-4c51-87d3-d2d3125cfac1}, !- Handle
  Office WholeBuilding - Sm Office,       !- Name
  ,                                       !- Default Construction Set Name
  {09f83373-2543-4efe-ad90-7facebecbcbb}, !- Default Schedule Set Name
  {c9f3a3a1-7407-4eab-bb64-27cdfc8e7a35}, !- Group Rendering Name
  {58b7ecf6-9d4d-4d56-95e8-b61a0fed9557}, !- Design Specification Outdoor Air Object Name
  ,                                       !- Standards Template
  Office,                                 !- Standards Building Type
  WholeBuilding - Sm Office;              !- Standards Space Type
```

The test passes but generates this warning from the forward translator:
`[openstudio.energyplus.ForwardTranslator] <0> Actuator 'Core_ZNZN_Light1_Actuator' references a SpaceLoad 'Office WholeBuilding - Sm Office Lights' attached to SpaceType 'Office WholeBuilding - Sm Office', with multiple spaces. Check your EMS programs to make sure your actuators are correct.
`

What appears in the .idf:

```
EnergyManagementSystem:Actuator,
  Core_ZNZN_Light1_Actuator,              !- Name
  Core_ZN ZN Office WholeBuilding - Sm Office Lights, !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type

EnergyManagementSystem:Actuator,
  Perimeter_ZN_1ZN_Light1_Actuator,       !- Name
  Core_ZN ZN Office WholeBuilding - Sm Office Lights, !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

All of the actuators point to the same shared lights object. That's a bug.

And it errors out now in OS 3.5.1:
```
   ** Severe  ** Invalid Actuated Component Unique Name =CORE_ZN ZN OFFICE WHOLEBUILDING - SM OFFICE LIGHTS
   **   ~~~   ** Entered in EnergyManagementSystem:Actuator=CORE_ZNZN_LIGHT1_ACTUATOR
```

It seems there are two issues here:
1) There is a bug in openstudio-standards; the lights object needs to be broken out by zone or space before applying EMS code
2) The forward translator simply can't handle shared space/zone lights objects required by EMS.  Ideally, it would take a shared space type resource like the lights object and make zone individually for each space if shared by EMS.  Or we can say you can't use shared space type resources with EMS. 

I think I can fix openstudio-standards by creating individual space light objects in OS 3.5.1, which means this issue is no longer a blocker. @lymereJ correct me here if you don't think that's possible.
@lymereJ @jmarrec Update: I've got a decent workaround [implemented in openstudio-standards](https://github.com/NREL/openstudio-standards/pull/1447).  I clone the space type lights object to each individual space.  Works with both OSv3.2.1 and OSv3.5.1.

Given the workaround, this issue is no longer an OpenStudio blocker for openstudio-standards.
Should use `getSpaceLoadParent`? https://github.com/NREL/OpenStudio/blob/1f8353e48d5bbb441b5d1b96ac8b3d877f5df457/src/energyplus/ForwardTranslator.cpp#L228
This was tricky back in the day because OS didnt use ZoneLists, but E+ did, etc.  The constructors were built with the following

https://github.com/NREL/OpenStudio/blob/99e001d02545ad4c65938f49b411179418662f9f/src/model/EnergyManagementSystemActuator.hpp#L62-L72

I would look at the constructor first to make sure the assumptions are still valid, given the space changes in E+, etc
@lymereJ Note that in your "Steps to Reproduce" section above, the `light` variable is unused. Should it be passed into the first position of `EnergyManagementSystemActuator.new(...)`?
yeah, i think the light object goes first, and the TZ or space goes last.
https://github.com/NREL/OpenStudio/blob/develop/src/model/test/EnergyManagementSystemActuator_GTest.cpp#L215
https://github.com/NREL/OpenStudio/blob/develop/src/model/test/EnergyManagementSystemActuator_GTest.cpp#L258
@joseph-robertson - You're correct, may bad. The code that I have in "Steps to Reproduce" generates the following actuator (incorrect as well), not the one that's in "Current Behavior". Not sure why I put `space1` instead of `light`.

```
EnergyManagementSystem:Actuator,
  Energy_Management_System_Actuator_1,    !- Name
  Space 1,                                !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

I'll correct that line in "Step to Reproduce". Thanks!
@lymereJ is an option for you now to just disable the space feature when forward translating?
> This was tricky back in the day because OS didnt use ZoneLists, but E+ did, etc. The constructors were built with the following
> 
> https://github.com/NREL/OpenStudio/blob/99e001d02545ad4c65938f49b411179418662f9f/src/model/EnergyManagementSystemActuator.hpp#L62-L72

Shouldn't these take in a SpaceLoadInstance instead of a ModelObject given the comment? I could see it going really wrong...
> @lymereJ is an option for you now to just disable the space feature when forward translating?

@jmarrec, I believe that we don't want to do that, this is for OpenStudio-Standards. I'll let @mdahlhausen confirm.
> > @lymereJ is an option for you now to just disable the space feature when forward translating?
> 
> @jmarrec, I believe that we don't want to do that, this is for OpenStudio-Standards. I'll let @mdahlhausen confirm.

yeah, that's not a workable solution.  People are build models using openstudio-standards, often in third-party software. I don't want to require third-party developers to have to disable the space feature when forward translating. Especially for end-users who might not know how to disable it. 

OK. I'm asking because this is marked as blocker, we're close to release date, and we have the existing API to retain.
I'll try to figure something out in the next couple of days that aims to support this without breaking api, I'll likely ask for thoughts/decisions as I dig down.
not sure if this helps with the debugging, but here is a measure that reproduces the EMS Demand Management example#9 and uses the Actuator on the lights object.
https://github.com/NREL/OpenStudio-EMS-Measures/blob/master/Measures/m_9_example_9_demand_management/measure.rb#L301

I'm going to try to see if there is a workaround in openstudio-standards.
i just checked and this does work in OS <=3.2 but not in OS 3.5.1

require 'openstudio'
model = OpenStudio::Model.exampleModel()
spaceType1 = model.getSpaceTypes()[0]
space1 = model.getSpaces()[0]
tz1 = model.getThermalZones()[0]

light = space1.spaceType.get.lights[0]
actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light, 'Lights', 'Electricity Rate', space1)

ft = OpenStudio::EnergyPlus::ForwardTranslator.new
w = ft.translateModel(model)

my bet it has something to do with no more ZoneLists or the new spaces

![image](https://user-images.githubusercontent.com/2235296/225111019-2ac827ca-3591-401e-b02e-c6943a98d69c.png)

looks like the actuators changed to use Spaces instead of Thermal Zones according to the .EDD

![image](https://user-images.githubusercontent.com/2235296/225112539-043cc941-c94d-441e-91e5-893a1b62d45b.png)

my guess is to use the space.name https://github.com/NREL/OpenStudio/blob/develop/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp#L124
instead of the thermal zone name

and something similiar here https://github.com/NREL/OpenStudio/blob/develop/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp#L105 
for getting the space name from the spacetype.

Some more context: 
Running test_small_office.rb for 90.1-2016 and ASHRAE 169-2013-5A

In OS 3.2.1:

```
OS:EnergyManagementSystem:Sensor,
  {9d59be4e-d960-47c1-aa96-6783eb166770}, !- Handle
  Core_ZNZN_LSr,                          !- Name
  Core_ZN ZN,                             !- Output Variable or Output Meter Index Key Name
  Zone Lights Electricity Rate;           !- Output Variable or Output Meter Name

OS:EnergyManagementSystem:InternalVariable,
  {496b4e8d-6dbc-49c2-8fd6-f0a0292d0d74}, !- Handle
  Core_ZNZN_Area,                         !- Name
  Core_ZN ZN,                             !- Internal Data Index Key Name
  Zone Floor Area;                        !- Internal Data Type

OS:EnergyManagementSystem:Actuator,
  {4936ef85-4857-41ae-b64f-5308c174d49f}, !- Handle
  Core_ZNZN_Light1_Actuator,              !- Name
  {a5e82b87-ce0f-4588-9715-85b90f56135a}, !- Actuated Component Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type

OS:EnergyManagementSystem:Actuator,
  {69231cf4-fc89-48f6-a304-29cadfe9f63c}, !- Handle
  Perimeter_ZN_1ZN_Light1_Actuator,       !- Name
  {a5e82b87-ce0f-4588-9715-85b90f56135a}, !- Actuated Component Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

actuated component is:

```
OS:Lights,
  {a5e82b87-ce0f-4588-9715-85b90f56135a}, !- Handle
  Office WholeBuilding - Sm Office Lights, !- Name
  {72e4e8c6-2310-41ff-856b-20a2cebb0674}, !- Lights Definition Name
  {629a271e-7460-4c51-87d3-d2d3125cfac1}, !- Space or SpaceType Name
  ,                                       !- Schedule Name
  1,                                      !- Fraction Replaceable
  ,                                       !- Multiplier
  General;                                !- End-Use Subcategory
```

which is used by this space type object:

```
OS:SpaceType,
  {629a271e-7460-4c51-87d3-d2d3125cfac1}, !- Handle
  Office WholeBuilding - Sm Office,       !- Name
  ,                                       !- Default Construction Set Name
  {09f83373-2543-4efe-ad90-7facebecbcbb}, !- Default Schedule Set Name
  {c9f3a3a1-7407-4eab-bb64-27cdfc8e7a35}, !- Group Rendering Name
  {58b7ecf6-9d4d-4d56-95e8-b61a0fed9557}, !- Design Specification Outdoor Air Object Name
  ,                                       !- Standards Template
  Office,                                 !- Standards Building Type
  WholeBuilding - Sm Office;              !- Standards Space Type
```

The test passes but generates this warning from the forward translator:
`[openstudio.energyplus.ForwardTranslator] <0> Actuator 'Core_ZNZN_Light1_Actuator' references a SpaceLoad 'Office WholeBuilding - Sm Office Lights' attached to SpaceType 'Office WholeBuilding - Sm Office', with multiple spaces. Check your EMS programs to make sure your actuators are correct.
`

What appears in the .idf:

```
EnergyManagementSystem:Actuator,
  Core_ZNZN_Light1_Actuator,              !- Name
  Core_ZN ZN Office WholeBuilding - Sm Office Lights, !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type

EnergyManagementSystem:Actuator,
  Perimeter_ZN_1ZN_Light1_Actuator,       !- Name
  Core_ZN ZN Office WholeBuilding - Sm Office Lights, !- Actuated Component Unique Name
  Lights,                                 !- Actuated Component Type
  Electricity Rate;                       !- Actuated Component Control Type
```

All of the actuators point to the same shared lights object. That's a bug.

And it errors out now in OS 3.5.1:
```
   ** Severe  ** Invalid Actuated Component Unique Name =CORE_ZN ZN OFFICE WHOLEBUILDING - SM OFFICE LIGHTS
   **   ~~~   ** Entered in EnergyManagementSystem:Actuator=CORE_ZNZN_LIGHT1_ACTUATOR
```

It seems there are two issues here:
1) There is a bug in openstudio-standards; the lights object needs to be broken out by zone or space before applying EMS code
2) The forward translator simply can't handle shared space/zone lights objects required by EMS.  Ideally, it would take a shared space type resource like the lights object and make zone individually for each space if shared by EMS.  Or we can say you can't use shared space type resources with EMS. 

I think I can fix openstudio-standards by creating individual space light objects in OS 3.5.1, which means this issue is no longer a blocker. @lymereJ correct me here if you don't think that's possible.
@lymereJ @jmarrec Update: I've got a decent workaround [implemented in openstudio-standards](https://github.com/NREL/openstudio-standards/pull/1447).  I clone the space type lights object to each individual space.  Works with both OSv3.2.1 and OSv3.5.1.

Given the workaround, this issue is no longer an OpenStudio blocker for openstudio-standards.

Fix patch:
diff --git a/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_6_0_TBD.md b/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_6_0_TBD.md
index 5d370f1ae74..bc3567da615 100644
--- a/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_6_0_TBD.md
+++ b/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_6_0_TBD.md
@@ -77,6 +77,8 @@ You can also refer to the [OpenStudio SDK Python Binding Version Compatibility M
 ## Minor changes and bug fixes
 
 
+* [#4828](https://github.com/NREL/OpenStudio/pull/4828) - Fix Space load-based actuator for spaces are named based on thermal zone name
+    * As part of this PR, the optional field at the end `Zone Name` is replaced with `Zone or Space` and some API changes are there around it. The only minor breaking one is that `boost::optional<ModelObject> zoneName()` (deprecated) will now return either a Zone or a Space. Before if you called setSpace it would store the space's ThermalZone, now it stores the Space itself. This is unlikely to affect most users.
 
 **Deprecated methods removed**:
 
diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd
index ec27818b8ee..d91c19dfadc 100644
--- a/resources/model/OpenStudio.idd
+++ b/resources/model/OpenStudio.idd
@@ -36395,9 +36395,14 @@ OS:EnergyManagementSystem:Actuator,
   A5, \field Actuated Component Control Type
        \required-field
        \type alpha
-  A6; \field Zone Name
+  A6; \field Zone or Space Name
+       \note This field is useful for a SpaceLoadInstance that is assigned to a SpaceType
+       \note because internally E+ will duplicate the instances and you need to access the final name
+       \note If you are using the Space Translation of the ForwardTranslator (which is defaulted on) this should be set to a Space
+       \note If not then use a ThermalZone
        \type object-list
-       \object-list AllObjects
+       \object-list SpaceNames
+       \object-list ThermalZoneNames
 
 OS:EnergyManagementSystem:ProgramCallingManager,
        \extensible:1 - repeat last field, remembering to remove ; from "inner" fields.
diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp
index 763efd4dd25..1fcc58903f8 100644
--- a/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp
+++ b/src/energyplus/ForwardTranslator/ForwardTranslateEnergyManagementSystemActuator.cpp
@@ -52,10 +52,14 @@
 #include "../../model/ThermalZone.hpp"
 #include "../../model/ThermalZone_Impl.hpp"
 
+#include "../../utilities/core/Compare.hpp"
+
 #include <utilities/idd/EnergyManagementSystem_Actuator_FieldEnums.hxx>
 #include "../../utilities/idd/IddEnums.hpp"
 #include <utilities/idd/IddEnums.hxx>
 
+#include <algorithm>
+
 using namespace openstudio::model;
 
 using namespace std;
@@ -65,113 +69,203 @@ namespace openstudio {
 namespace energyplus {
 
   boost::optional<IdfObject> ForwardTranslator::translateEnergyManagementSystemActuator(EnergyManagementSystemActuator& modelObject) {
-    boost::optional<std::string> s;
 
-    IdfObject idfObject(openstudio::IddObjectType::EnergyManagementSystem_Actuator);
+    const boost::optional<ModelObject> actuatedComponent_ = modelObject.actuatedComponent();
+    if (!actuatedComponent_) {
+      LOG(Error, "Actuated Component for Actuator " << modelObject.nameString() << " does not exist, it will not be translated.");
+      return boost::none;
+    }
 
-    //Name
-    s = modelObject.name();
-    if (s) {
-      idfObject.setName(*s);
+    // Start by dealing with "OS:Site" and "OS:WeatherFile" that are special ones (will not pass the test on `m.name()` below
+    if (actuatedComponent_->iddObjectType() == openstudio::IddObjectType::OS_Site
+        || actuatedComponent_->iddObjectType() == openstudio::IddObjectType::OS_WeatherFile) {
+      IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::EnergyManagementSystem_Actuator, modelObject);
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, "Environment");
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, "Weather Data");
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, modelObject.actuatedComponentControlType());
+      return idfObject;
     }
-    const boost::optional<ModelObject> m_opt = modelObject.actuatedComponent();
-    if (m_opt) {
-      ModelObject m = m_opt.get();
-
-      // Start by dealing with "OS:Site" and "OS:WeatherFile" that are special ones (will not pass the test on `m.name()` below
-      if (m.iddObjectType() == openstudio::IddObjectType::OS_Site || m.iddObjectType() == openstudio::IddObjectType::OS_WeatherFile) {
-        idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, "Environment");
-        idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, "Weather Data");
-        idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, modelObject.actuatedComponentControlType());
-        m_idfObjects.push_back(idfObject);
-        return idfObject;
-      }
 
-      // The component should have a name
-      if (!m.name()) {
-        LOG(Error, "Actuated Component Name for Actuator '" << modelObject.nameString() << "' does not exist, it will not be translated.");
+    // As this point, it MUST have a name, as we dealt with the special ones already
+    if (!actuatedComponent_->name()) {
+      LOG(Error, "Actuated Component Name for Actuator '" << modelObject.nameString() << "' does not exist, it will not be translated.");
+      return boost::none;
+    }
+
+    // check if actuatedComponent is a SpaceLoad
+    auto load_ = actuatedComponent_->optionalCast<model::SpaceLoadInstance>();
+    if (!load_) {
+      // Classic case, we just write it
+      IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::EnergyManagementSystem_Actuator, modelObject);
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, actuatedComponent_->nameString());
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, modelObject.actuatedComponentType());
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, modelObject.actuatedComponentControlType());
+      return idfObject;
+    }
+
+    // SpaceLoadInstance: check if first if it's assigned to a single space
+    auto space_ = load_->space();
+    if (space_) {
+      // if load is assigned to a single space instead of a space type then the name will not be changed in EnergyPlus
+      IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::EnergyManagementSystem_Actuator, modelObject);
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, actuatedComponent_->nameString());
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, modelObject.actuatedComponentType());
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, modelObject.actuatedComponentControlType());
+      return idfObject;
+    }
+
+    // At this point the SpaceLoadInstance is not assigned to a space, so it's assigned to a SpaceType or nothing
+
+    auto spaceType_ = load_->spaceType();
+    if (!spaceType_) {
+      LOG(Error, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString()
+                              << "' which is not associated with a ThermalZone, it will not be translated.");
+      return boost::none;
+    }
+
+    // Deal with the SpaceType case...
+
+    // Case 1: the user correctly assigned a Space or ThermalZone to it
+    if (const boost::optional<Space> specificSpace_ = modelObject.space()) {
+      // Assert the space has a thermalZone attached to it.
+      auto tz_ = specificSpace_->thermalZone();
+      if (!tz_) {
+        LOG(Error, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString()
+                                << "' and specified that it wanted to be attached to the Space '" << specificSpace_->nameString()
+                                << "' but the Space has no Thermal Zone, so it will not be translated.");
         return boost::none;
       }
 
-      // check if actuatedComponent is a SpaceLoad
-      if (auto load = m.optionalCast<model::SpaceLoadInstance>()) {
-        const boost::optional<ModelObject> m_zN = modelObject.zoneName();
-        // if SpaceLoad, check if thermalzone names exist
-        auto space = load->space();
-        auto spaceType = load->spaceType();
-        if (spaceType) {
-          if (m_zN) {
-            //ZoneName object exists so set name to be the concatonation of it plus the spaceloadobject
-            std::string tz_name = m_zN.get().nameString() + " " + m.nameString();
-            idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, tz_name);
-            idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, modelObject.actuatedComponentType());
-            idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, modelObject.actuatedComponentControlType());
-
-            m_idfObjects.push_back(idfObject);
-            return idfObject;
-          }
-          //ZoneName object does not exist so try and translate anyway
-
-          // should not also have a space assigned
-          OS_ASSERT(!space);
-
-          // the load references a space type, this means it will reference a zonelist in EnergyPlus
-          // in EnergyPlus, each load in a zonelist is duplicated into each zone with a new name based on the zone
-          boost::optional<IdfObject> result;
-          for (const auto& space : spaceType->spaces()) {
-            auto tz = space.thermalZone();
-            if (tz) {
-              std::string tz_name = tz.get().nameString() + " " + m.nameString();
-              idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, tz_name);
-              idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, modelObject.actuatedComponentType());
-              idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, modelObject.actuatedComponentControlType());
-              if (!result) {
-                result = idfObject;
-              }
-            } else {
-              LOG(Error, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load.get().name().get()
-                                      << "' which is not associated with a ThermalZone, it will not be translated.");
-            }
-          }
-          //Give WArning that spaceType has multiple spaces
-          if (m_forwardTranslatorOptions.excludeSpaceTranslation() && spaceType->spaces().size() > 1) {
-            LOG(Warn, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load.get().name().get()
-                                   << "' attached to SpaceType '" << spaceType.get().nameString()
-                                   << "', with multiple spaces. Check your EMS programs to make sure your actuators are correct.");
-          }
-          // return the first idf object
-          if (result) {
-            m_idfObjects.push_back(result.get());
-          }
-          return result;
+      std::string zoneOrSpaceName = specificSpace_->nameString();
 
-        } else if (space) {
+      // Try to be helpful in case the user assigned a Space, but the FT doesn't translate spaces
+      if (m_forwardTranslatorOptions.excludeSpaceTranslation()) {
+        LOG(Warn, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString()
+                               << "' and specified that it wanted to be attached to the Space '" << specificSpace_->nameString()
+                               << "' but you have turned off ForwardTranslation's Space Feature. Falling back to using the attached ThermalZone '"
+                               << tz_->nameString() << "'.");
+        zoneOrSpaceName = tz_->nameString();
+      }
 
-          // if load is assigned to a single space instead of a space type then the name will not be changed in EnergyPlus
-          idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, m.nameString());
-          idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, modelObject.actuatedComponentType());
-          idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, modelObject.actuatedComponentControlType());
-          m_idfObjects.push_back(idfObject);
+      IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::EnergyManagementSystem_Actuator, modelObject);
+      const std::string spaceLoadNameForEMS = zoneOrSpaceName + " " + actuatedComponent_->nameString();
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, spaceLoadNameForEMS);
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, modelObject.actuatedComponentType());
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, modelObject.actuatedComponentControlType());
+      return idfObject;
+    }
 
-          return idfObject;
-        } else {
-          LOG(Error, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load.get().name().get()
-                                  << "' which is not associated with a ThermalZone, it will not be translated.");
-          return boost::none;
+    if (const boost::optional<ThermalZone> specificZone_ = modelObject.thermalZone()) {
+      auto spaces = specificZone_->spaces();
+      if (spaces.empty()) {
+        LOG(Error, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString()
+                                << "' and specified that it wanted to be attached to the ThermalZone '" << specificZone_->nameString()
+                                << "' but the Thermal Zone has no Spaces, so it will not be translated.");
+        return boost::none;
+      }
+
+      std::string zoneOrSpaceName = specificZone_->nameString();
+
+      if (!m_forwardTranslatorOptions.excludeSpaceTranslation()) {
+        if (spaces.size() == 1) {
+          zoneOrSpaceName = spaces.front().nameString();
+          LOG(Warn, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString()
+                                 << "' and specified that it wanted to be attached to the Thermal Zone '" << specificZone_->nameString()
+                                 << "' but you have turned on ForwardTranslation's Space Feature. Falling back to using the attached Space '"
+                                 << zoneOrSpaceName << "' since there is only 1.");
+        } else {  // if (spaces.size() > 1) {
+          std::sort(spaces.begin(), spaces.end(), WorkspaceObjectNameLess());
+          zoneOrSpaceName = spaces.front().nameString();
+          // TODO: do we grab the first space or just don't translate it?
+          LOG(Error, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString()
+                                  << "' and specified that it wanted to be attached to the Thermal Zone '" << specificZone_->nameString()
+                                  << "' but you have turned on ForwardTranslation's Space Feature. Your Thermal Zone has multiple spaces "
+                                     "attached. Falling back to using the first Space '"
+                                  << zoneOrSpaceName << "'.");
         }
+      }
+
+      // ZoneName object exists so set name to be the concatenation of it plus the spaceloadobject
+      IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::EnergyManagementSystem_Actuator, modelObject);
+      const std::string spaceLoadNameForEMS = zoneOrSpaceName + " " + actuatedComponent_->nameString();
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, spaceLoadNameForEMS);
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, modelObject.actuatedComponentType());
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, modelObject.actuatedComponentControlType());
+      return idfObject;
+    }
+
+    // ZoneName object does not exist so try and translate anyway
+
+    // the load references a space type, this means it will reference a ZoneList (if excludeSpaceTranslation = true) or a SpaceList in EnergyPlus
+    // in EnergyPlus, each load in a ZoneList is duplicated into each zone with a new name based on the zone, same for SpaceList
+    {
+      auto spaces = spaceType_->spaces();
+      if (spaces.empty()) {
+        LOG(Error, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString()
+                                << "' and specified that it wanted to be attached to the SpaceType '" << spaceType_->nameString()
+                                << "' but the Space Type has no Spaces, so it will not be translated.");
+        return boost::none;
+      }
 
-        // Classic case, we just write it
+      std::string zoneOrSpaceName;
+
+      if (!m_forwardTranslatorOptions.excludeSpaceTranslation()) {
+        if (spaces.size() == 1) {
+          zoneOrSpaceName = spaces.front().nameString();
+          LOG(Warn, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString() << "' attached to the SpaceType '"
+                                 << spaceType_->nameString()
+                                 << "' but you have turned on ForwardTranslation's Space Feature. Falling back to using the attached Space '"
+                                 << zoneOrSpaceName << "' since there is only 1.");
+        } else {  // if (spaces.size() > 1) {
+          // TODO: do we grab the first space or just don't translate it?
+          std::sort(spaces.begin(), spaces.end(), WorkspaceObjectNameLess());
+          zoneOrSpaceName = spaces.front().nameString();
+          LOG(Error, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString()
+                                  << "' attached to the SpaceType '" << spaceType_->nameString()
+                                  << "' but you have turned on ForwardTranslation's Space Feature. The Space Type has multiple spaces "
+                                     "attached. Falling back to using the first Space '"
+                                  << zoneOrSpaceName << "'.");
+        }
       } else {
-        idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, m.nameString());
-        idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, modelObject.actuatedComponentType());
-        idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, modelObject.actuatedComponentControlType());
-        m_idfObjects.push_back(idfObject);
-        return idfObject;
+        // Not translating Spaces
+        std::set<std::string> zoneNames;
+        for (const auto& space : spaceType_->spaces()) {
+          if (auto tz_ = space.thermalZone()) {
+            zoneNames.insert(tz_->nameString());
+          }
+        }
+        if (zoneNames.empty()) {
+          LOG(Error, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString()
+                                  << "' attached to the SpaceType '" << spaceType_->nameString()
+                                  << "' but the Space Type has zero spaces attached to any Thermal Zones, so it will not be translated.");
+          return boost::none;
+        }
+        zoneOrSpaceName = *(zoneNames.begin());
+        if (zoneNames.size() == 1) {
+          LOG(Warn, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString() << "' attached to the SpaceType '"
+                                 << spaceType_->nameString()
+                                 << "' but you have turned off ForwardTranslation's Space Feature. Falling back to using the attached ThermalZone '"
+                                 << zoneOrSpaceName << "' since there is only 1.");
+        } else {  // if (zoneNames.size() > 1) {
+          // TODO: do we grab the first space or just don't translate it?
+          LOG(Error, "Actuator '" << modelObject.nameString() << "' references a SpaceLoad '" << load_->nameString()
+                                  << "' attached to the SpaceType '" << spaceType_->nameString()
+                                  << "' but you have turned off ForwardTranslation's Space Feature. "
+                                     "Your SpaceType ends up linked to multiples Thermal Zones. Falling back to using the first Thermal Zone '"
+                                  << zoneOrSpaceName << "'.");
+        }
       }
-    } else {
-      LOG(Error, "Actuated Component for Actuator " << modelObject.nameString() << " does not exist, it will not be translated.");
-      return boost::none;
+
+      // ZoneName object exists so set name to be the concatenation of it plus the spaceloadobject
+      IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::EnergyManagementSystem_Actuator, modelObject);
+      const std::string spaceLoadNameForEMS = zoneOrSpaceName + " " + actuatedComponent_->nameString();
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, spaceLoadNameForEMS);
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, modelObject.actuatedComponentType());
+      idfObject.setString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, modelObject.actuatedComponentControlType());
+      return idfObject;
     }
+
+    return boost::none;
   }
 
 }  // namespace energyplus
diff --git a/src/energyplus/Test/EMS_GTest.cpp b/src/energyplus/Test/EMS_GTest.cpp
index 36f9eec920b..afb0587a440 100644
--- a/src/energyplus/Test/EMS_GTest.cpp
+++ b/src/energyplus/Test/EMS_GTest.cpp
@@ -155,6 +155,7 @@
 #include "../../utilities/sql/SqlFile.hpp"
 #include "../../utilities/idf/IdfFile.hpp"
 #include "../../utilities/idf/IdfObject.hpp"
+#include "../../utilities/core/Compare.hpp"
 
 #include <utilities/idd/OS_EnergyManagementSystem_Sensor_FieldEnums.hxx>
 #include <utilities/idd/EnergyManagementSystem_Sensor_FieldEnums.hxx>
@@ -195,8 +196,8 @@
 
 #include <resources.hxx>
 
+#include <algorithm>
 #include <sstream>
-
 #include <vector>
 
 using namespace openstudio::energyplus;
@@ -654,9 +655,10 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuatorSpaceLoad_SpaceType_EMS) {
   Building building = model.getUniqueModelObject<Building>();
 
   ThermalZone zone1(model);
-  zone1.setName("Thermal Zone");
+  zone1.setName("Zone1");
 
   Space space(model);
+  space.setName("Space1");
   SpaceType spaceType(model);
   space.setThermalZone(zone1);
   space.setSpaceType(spaceType);
@@ -671,30 +673,63 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuatorSpaceLoad_SpaceType_EMS) {
   // add actuator
   std::string ControlType = "NaturalGas Rate";
   std::string ComponentType = "GasEquipment";
-  EnergyManagementSystemActuator fanActuator(gasEquip, ComponentType, ControlType);
+  EnergyManagementSystemActuator gasEquipmentActuator(gasEquip, ComponentType, ControlType);
   std::string actName = "Gas Equip Actuator";
-  fanActuator.setName(actName);
-
-  ForwardTranslator forwardTranslator;
-  Workspace workspace = forwardTranslator.translateModel(model);
-  EXPECT_EQ(0u, forwardTranslator.errors().size());
-  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
+  gasEquipmentActuator.setName(actName);
 
-  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
+  ForwardTranslator ft;
 
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
-  EXPECT_EQ("Gas_Equip_Actuator", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
-  //Should have TZ in the name since the load is attached to a spacetype with only 1 space
-  EXPECT_EQ("Thermal Zone Gas Equip", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
-  EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
-  EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  // When excluding space translation (historical behavior)
+  {
+    ft.setExcludeSpaceTranslation(true);
+
+    Workspace workspace = ft.translateModel(model);
+    EXPECT_EQ(0, ft.errors().size());
+    EXPECT_EQ(1, ft.warnings().size());
+    EXPECT_EQ("Actuator 'Gas_Equip_Actuator' references a SpaceLoad 'Gas Equip' attached to the SpaceType 'Space Type 1' but you have turned off "
+              "ForwardTranslation's Space Feature. Falling back to using the attached ThermalZone 'Zone1' since there is only 1.",
+              ft.warnings().front().logMessage());
+    EXPECT_EQ(1, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
+
+    WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
+
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
+    EXPECT_EQ("Gas_Equip_Actuator", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
+    //Should have TZ in the name since the load is attached to a spacetype with only 1 space
+    EXPECT_EQ("Zone1 Gas Equip", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
+    EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
+    EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  }
 
-  // model.save(toPath("./EMS_example.osm"), true);
-  // workspace.save(toPath("./EMS_example.idf"), true);
+  // When including Space translation (new E+ 9.6.0)
+  {
+    ft.setExcludeSpaceTranslation(false);
+
+    Workspace workspace = ft.translateModel(model);
+    EXPECT_EQ(0u, ft.errors().size());
+    EXPECT_EQ(1, ft.warnings().size());
+    EXPECT_EQ("Actuator 'Gas_Equip_Actuator' references a SpaceLoad 'Gas Equip' attached to the SpaceType 'Space Type 1' but you have turned on "
+              "ForwardTranslation's Space Feature. Falling back to using the attached Space 'Space1' since there is only 1.",
+              ft.warnings().front().logMessage());
+    EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
+
+    WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
+
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
+    EXPECT_EQ("Gas_Equip_Actuator", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
+    //Should have Space in the name since the load is attached to a spacetype with only 1 space
+    EXPECT_EQ("Space1 Gas Equip", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
+    EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
+    EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  }
 }
+
 TEST_F(EnergyPlusFixture, ForwardTranslatorActuatorSpaceLoad_Space2_EMS) {
   Model model;
 
@@ -747,9 +782,10 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuatorSpaceLoad_SpaceType2_EMS) {
   Building building = model.getUniqueModelObject<Building>();
 
   ThermalZone zone1(model);
-  zone1.setName("Thermal Zone");
+  zone1.setName("Zone1");
 
   Space space(model);
+  space.setName("Space1");
   SpaceType spaceType(model);
   space.setThermalZone(zone1);
   space.setSpaceType(spaceType);
@@ -768,26 +804,61 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuatorSpaceLoad_SpaceType2_EMS) {
   std::string actName = "Electric Equip Actuator";
   fanActuator.setName(actName);
 
-  ForwardTranslator forwardTranslator;
-  Workspace workspace = forwardTranslator.translateModel(model);
-  EXPECT_EQ(0u, forwardTranslator.errors().size());
-  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
-
-  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
+  ForwardTranslator ft;
 
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
-  EXPECT_EQ("Electric_Equip_Actuator", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
-  //Should have TZ in the name since the load is attached to a spacetype with only 1 space
-  EXPECT_EQ("Thermal Zone Electric Equip", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
-  EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
-  EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  // When excluding space translation (historical behavior)
+  {
+    ft.setExcludeSpaceTranslation(true);
+
+    Workspace workspace = ft.translateModel(model);
+    EXPECT_EQ(0u, ft.errors().size());
+    EXPECT_EQ(1, ft.warnings().size());
+    EXPECT_EQ("Actuator 'Electric_Equip_Actuator' references a SpaceLoad 'Electric Equip' attached to the SpaceType 'Space Type 1' but you have "
+              "turned off ForwardTranslation's Space Feature. Falling back to using the attached ThermalZone 'Zone1' since there is only 1.",
+              ft.warnings().front().logMessage());
+
+    EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
+
+    WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
+
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
+    EXPECT_EQ("Electric_Equip_Actuator", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
+    //Should have TZ in the name since the load is attached to a spacetype with only 1 space
+    EXPECT_EQ("Zone1 Electric Equip", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
+    EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
+    EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  }
 
-  // model.save(toPath("./EMS_example.osm"), true);
-  // workspace.save(toPath("./EMS_example.idf"), true);
+  // When including Space translation (new E+ 9.6.0)
+  {
+    ft.setExcludeSpaceTranslation(false);
+
+    Workspace workspace = ft.translateModel(model);
+    EXPECT_EQ(0u, ft.errors().size());
+    EXPECT_EQ(1, ft.warnings().size());
+    EXPECT_EQ("Actuator 'Electric_Equip_Actuator' references a SpaceLoad 'Electric Equip' attached to the SpaceType 'Space Type 1' but you have "
+              "turned on ForwardTranslation's Space Feature. Falling back to using the attached Space 'Space1' since there is only 1.",
+              ft.warnings().front().logMessage());
+
+    EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
+
+    WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
+
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
+    EXPECT_EQ("Electric_Equip_Actuator", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
+    //Should have Space in the name since the load is attached to a spacetype with only 1 space
+    EXPECT_EQ("Space1 Electric Equip", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
+    EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
+    EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  }
 }
+
 TEST_F(EnergyPlusFixture, ForwardTranslatorActuatorSpaceLoad3_EMS) {
   Model model;
 
@@ -836,10 +907,12 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuatorSpaceLoad_SpaceTypes_EMS) {
   SpaceType spaceType(model);
 
   Space space1(model);
+  space1.setName("Space1");
   space1.setThermalZone(zone1);
   space1.setSpaceType(spaceType);
 
   Space space2(model);
+  space2.setName("Space2");
   space2.setThermalZone(zone2);
   space2.setSpaceType(spaceType);
 
@@ -857,29 +930,63 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuatorSpaceLoad_SpaceTypes_EMS) {
   std::string actName = "Electric Equip Actuator";
   fanActuator.setName(actName);
 
-  ForwardTranslator forwardTranslator;
-  forwardTranslator.setExcludeSpaceTranslation(true);
-  Workspace workspace = forwardTranslator.translateModel(model);
-  EXPECT_EQ(0u, forwardTranslator.errors().size());
-  //expect a warning since there are 2 spaces with the same spaceType
-  EXPECT_EQ(1u, forwardTranslator.warnings().size());
-  //expect 1 actuator since there are 2 spaces with the same spaceType but only 1 will get translated right now
-  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
-
-  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
+  ForwardTranslator ft;
 
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
-  EXPECT_EQ("Electric_Equip_Actuator", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
-  // cannot guarantee the order of which TZ gets translated first
-  //EXPECT_EQ("Thermal Zone 2 Electric Equip", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
-  EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
-  EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  // When excluding space translation (historical behavior)
+  {
+    ft.setExcludeSpaceTranslation(true);
+
+    ft.setExcludeSpaceTranslation(true);
+    Workspace workspace = ft.translateModel(model);
+    //expect an error since there are 2 spaces with the same spaceType that resolve to two dfferent zones, so the fallback is less safe than it there
+    // was only one, hence an error not a warning
+    EXPECT_EQ(1, ft.errors().size());
+    EXPECT_EQ("Actuator 'Electric_Equip_Actuator' references a SpaceLoad 'Electric Equip' attached to the SpaceType 'Space Type 1' but you have "
+              "turned off ForwardTranslation's Space Feature. Your SpaceType ends up linked to multiples Thermal Zones. Falling back to using the "
+              "first Thermal Zone 'Thermal Zone 1'.",
+              ft.errors().front().logMessage());
+    EXPECT_EQ(0, ft.warnings().size());
+    //expect 1 actuator since there are 2 zones with the same spaceType but only 1 will get translated right now
+    EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
+
+    WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
+
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
+    EXPECT_EQ("Electric_Equip_Actuator", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
+    EXPECT_EQ("Thermal Zone 1 Electric Equip", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
+    EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
+    EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  }
 
-  // model.save(toPath("./EMS_multi_spaces_spacetypes.osm"), true);
-  // workspace.save(toPath("./EMS_multi_spaces_spacetypes.idf"), true);
+  // When including Space translation (new E+ 9.6.0)
+  {
+    ft.setExcludeSpaceTranslation(false);
+
+    Workspace workspace = ft.translateModel(model);
+    //expect an error since there are 2 spaces with the same spaceType that resolve to two dfferent zones
+    EXPECT_EQ(1, ft.errors().size());
+    EXPECT_EQ(
+      "Actuator 'Electric_Equip_Actuator' references a SpaceLoad 'Electric Equip' attached to the SpaceType 'Space Type 1' but you have turned on "
+      "ForwardTranslation's Space Feature. The Space Type has multiple spaces attached. Falling back to using the first Space 'Space1'.",
+      ft.errors().front().logMessage());
+    EXPECT_EQ(0, ft.warnings().size());
+    //expect 1 actuator since there are 2 zones with the same spaceType but only 1 will get translated right now
+    EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
+
+    WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
+
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
+    EXPECT_EQ("Electric_Equip_Actuator", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
+    EXPECT_EQ("Space1 Electric Equip", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
+    EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
+    EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  }
 }
 
 Model prepareProgram_EMS() {
@@ -1887,32 +1994,64 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuator_exampleModel_Lights_EMS) {
   std::string ComponentType = "Lights";
   std::string ControlType = "Electricity Rate";
   EnergyManagementSystemActuator lightsActuator(lights[0], ComponentType, ControlType, space4.get());
-  EXPECT_EQ(space4.get().thermalZone().get().handle(), lightsActuator.zoneName().get().handle());
+  EXPECT_EQ(space4->handle(), lightsActuator.zoneOrSpace()->handle());
 
-  ForwardTranslator forwardTranslator;
-  Workspace workspace = forwardTranslator.translateModel(model);
-  EXPECT_TRUE(checkLogMessages(0, forwardTranslator.errors()));
-  //expect no warning since we are using the zoneName API
-  EXPECT_TRUE(checkLogMessages(0, forwardTranslator.warnings(),
-                               {"Object of type 'OS:ThermalZone' and named 'Thermal Zone 1' has DaylightingControl Objects assigned. The interior "
-                                "walls between Spaces will be merged. Make sure these are correctly Matched!"}));
-
-  //expect 1 actuator since there are 4 spaces with the same spaceType but only 1 will get translated right now
-  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
+  ForwardTranslator ft;
 
-  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
-
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
-  EXPECT_EQ("Energy_Management_System_Actuator_1", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
-  EXPECT_EQ("Thermal Zone 1 Lights 1", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
-  EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
-  ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
-  EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  // When excluding space translation (historical behavior)
+  {
+    ft.setExcludeSpaceTranslation(true);
+
+    // We get only a warning, since we can recover from it easily
+    Workspace workspace = ft.translateModel(model);
+    EXPECT_EQ(0u, ft.errors().size());
+    EXPECT_EQ(1, ft.warnings().size());
+    EXPECT_EQ(
+      "Actuator 'Energy_Management_System_Actuator_1' references a SpaceLoad 'Lights 1' attached to the SpaceType 'Space Type 1' but you have turned "
+      "off ForwardTranslation's Space Feature. Falling back to using the attached ThermalZone 'Thermal Zone 1' since there is only 1.",
+      ft.warnings().front().logMessage());
+
+    //expect 1 actuator since there are 4 spaces with the same spaceType but only 1 will get translated right now
+    EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
+
+    WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
+
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
+    EXPECT_EQ("Energy_Management_System_Actuator_1", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
+    EXPECT_EQ("Thermal Zone 1 Lights 1", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
+    EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
+    EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  }
 
-  //model.save(toPath("./EMS_actuator_exampleModel_lights.osm"), true);
-  //workspace.save(toPath("./EMS_actuator_exampleModel_lights.idf"), true);
+  // When including Space translation (new E+ 9.6.0)
+  {
+    ft.setExcludeSpaceTranslation(false);
+
+    // No warnings here (from EMS), the space is set
+    Workspace workspace = ft.translateModel(model);
+    EXPECT_EQ(0u, ft.errors().size());
+    EXPECT_EQ(1, ft.warnings().size());
+    EXPECT_EQ("Object of type 'OS:ThermalZone' and named 'Thermal Zone 1' has DaylightingControl Objects assigned. The interior walls between Spaces "
+              "will be merged. Make sure these are correctly Matched!",
+              ft.warnings().front().logMessage());
+
+    //expect 1 actuator since there are 4 spaces with the same spaceType but only 1 will get translated right now
+    EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
+
+    WorkspaceObject object = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator)[0];
+
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::Name, false));
+    EXPECT_EQ("Energy_Management_System_Actuator_1", object.getString(EnergyManagementSystem_ActuatorFields::Name, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false));
+    EXPECT_EQ("Space 4 Lights 1", object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false));
+    EXPECT_EQ(ComponentType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentType, false).get());
+    ASSERT_TRUE(object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false));
+    EXPECT_EQ(ControlType, object.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, false).get());
+  }
 }
 TEST_F(EnergyPlusFixture, ForwardTranslatorActuator_exampleModel_Electric_EMS) {
   //use spacetype with multiple spaces
@@ -1930,6 +2069,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuator_exampleModel_Electric_EMS) {
   std::vector<SpaceType> spaceTypes = model.getConcreteModelObjects<SpaceType>();
   std::vector<ThermalZone> thermalZone = model.getConcreteModelObjects<ThermalZone>();
   boost::optional<Space> space4 = model.getConcreteModelObjectByName<Space>("Space 4");
+  ASSERT_TRUE(space4);
   //this will create 1 zone in a zonelist
 
   //This is the EDD file for the spaceload actuators for this model so far
@@ -1944,60 +2084,79 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuator_exampleModel_Electric_EMS) {
   std::string ComponentType = "ElectricEquipment";
   std::string ControlType = "Electricity Rate";
   //actuator on first electricEquipment object
-  EnergyManagementSystemActuator electricActuator0(electricEquipment[0], ComponentType, ControlType);
-  //actuator on second electricEquipment object
-  EnergyManagementSystemActuator electricActuator1(electricEquipment[1], ComponentType, ControlType);
+  // NOTE: there is electricEquipment on a Space and one on a Space Type. I am VOLUNTARILY not setting the space4 for the Space Type one
+  if (electricEquipment[0].space()) {
+    EnergyManagementSystemActuator electricActuator0(electricEquipment[0], ComponentType, ControlType);
+    EnergyManagementSystemActuator electricActuator1(electricEquipment[1], ComponentType, ControlType);  // , space4.get());
+  } else {
+    // 0 is on a SpaceType, 1 is on a Space
+    EnergyManagementSystemActuator electricActuator0(electricEquipment[0], ComponentType, ControlType);  // , space4.get());
+    EnergyManagementSystemActuator electricActuator1(electricEquipment[1], ComponentType, ControlType);
+  }
 
-  ForwardTranslator forwardTranslator;
+  ForwardTranslator ft;
 
   // When excluding space translation (historical behavior)
   {
-    forwardTranslator.setExcludeSpaceTranslation(true);
-    Workspace workspace = forwardTranslator.translateModel(model);
+    ft.setExcludeSpaceTranslation(true);
 
-    EXPECT_TRUE(checkLogMessages(0, forwardTranslator.errors()));
-    //expect no warning since we are using the zoneName API
-    EXPECT_TRUE(checkLogMessages(0, forwardTranslator.warnings()));
-    //expect 2 actuator since there are 4 spaces with the same spaceType but only 1 will get translated right now
-    EXPECT_EQ(2u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
+    Workspace workspace = ft.translateModel(model);
+
+    // We get only a warning, since we can recover from it easily
+    EXPECT_EQ(0u, ft.errors().size());
+    EXPECT_EQ(1, ft.warnings().size());
+    EXPECT_EQ(
+      "Actuator 'Energy_Management_System_Actuator_2' references a SpaceLoad 'Electric Equipment 1' attached to the SpaceType 'Space Type 1' but you "
+      "have turned off ForwardTranslation's Space Feature. Falling back to using the attached ThermalZone 'Thermal Zone 1' since there is only 1.",
+      ft.warnings().front().logMessage());
 
     std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator);
-    OptionalString name0 = objects[0].getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName);
-    OptionalString name1 = objects[1].getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName);
-    std::string test0 = "Printer";
-    std::string test1 = "Thermal Zone 1 Electric Equipment 1";
-    //EXPECT_EQ(name0.get(),test0);
-    //EXPECT_EQ(name1.get(), test1);
-    EXPECT_TRUE((name0.get() == test0) || (name0.get() == test1));
-    EXPECT_TRUE((name1.get() == test0) || (name1.get() == test1));
+    //expect 2 actuator since there are 4 spaces with the same spaceType but only 1 will get translated right now
+    ASSERT_EQ(2, objects.size());
+
+    std::vector<std::string> actuatedNames;
+    std::transform(objects.cbegin(), objects.cend(), std::back_inserter(actuatedNames),
+                   [](const auto& wo) { return wo.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName).get(); });
+    std::sort(actuatedNames.begin(), actuatedNames.end());
+    EXPECT_EQ("Printer", actuatedNames.at(0));
+    EXPECT_EQ("Thermal Zone 1 Electric Equipment 1", actuatedNames.at(1));
     //model.save(toPath("./EMS_actuator_exampleModel_electric.osm"), true);
     //workspace.save(toPath("./EMS_actuator_exampleModel_electric.idf"), true);
   }
 
   // When including Space translation (new E+ 9.6.0)
   {
-    // TODO:
-    forwardTranslator.setExcludeSpaceTranslation(false);
-    Workspace workspace = forwardTranslator.translateModel(model);
-
-    EXPECT_TRUE(checkLogMessages(0, forwardTranslator.errors()));
-    //expect no warning since we are using the zoneName API
-    EXPECT_TRUE(checkLogMessages(0, forwardTranslator.warnings(),
-                                 {"Object of type 'OS:ThermalZone' and named 'Thermal Zone 1' has DaylightingControl Objects assigned. The interior "
-                                  "walls between Spaces will be merged. Make sure these are correctly Matched!"}));
+    ft.setExcludeSpaceTranslation(false);
+    Workspace workspace = ft.translateModel(model);
+
+    // NOTE: the space is NOT set on the Space Type one, and it has multiple spaces, so there will be an error. It will end up selecting the Space 1
+    // to set it though (it selects the Space sorted by name, so Space 1)
+    EXPECT_EQ(1u, ft.errors().size());
+    EXPECT_EQ("Actuator 'Energy_Management_System_Actuator_2' references a SpaceLoad 'Electric Equipment 1' attached to the SpaceType 'Space Type 1' "
+              "but you have turned on ForwardTranslation's Space Feature. The Space Type has multiple spaces attached. Falling back to using the "
+              "first Space 'Space 1'.",
+              ft.errors().front().logMessage());
+    EXPECT_EQ(1, ft.warnings().size());
+    EXPECT_EQ("Object of type 'OS:ThermalZone' and named 'Thermal Zone 1' has DaylightingControl Objects assigned. The interior walls between Spaces "
+              "will be merged. Make sure these are correctly Matched!",
+              ft.warnings().front().logMessage());
+
     //expect 2 actuator since there are 4 spaces with the same spaceType but only 1 will get translated right now
     EXPECT_EQ(2u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
 
     std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator);
-    OptionalString name0 = objects[0].getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName);
-    OptionalString name1 = objects[1].getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName);
-    std::string test0 = "Printer";
-    std::string test1 = "Thermal Zone 1 Electric Equipment 1";
-
-    EXPECT_TRUE((name0.get() == test0) || (name0.get() == test1));
-    EXPECT_TRUE((name1.get() == test0) || (name1.get() == test1));
+    //expect 2 actuator since there are 4 spaces with the same spaceType but only 1 will get translated right now
+    ASSERT_EQ(2, objects.size());
+
+    std::vector<std::string> actuatedNames;
+    std::transform(objects.cbegin(), objects.cend(), std::back_inserter(actuatedNames),
+                   [](const auto& wo) { return wo.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName).get(); });
+    std::sort(actuatedNames.begin(), actuatedNames.end());
+    EXPECT_EQ("Printer", actuatedNames.front());
+    EXPECT_EQ("Space 1 Electric Equipment 1", actuatedNames.back());
   }
 }
+
 TEST_F(EnergyPlusFixture, ForwardTranslatorActuator_API_EMS) {
   //use spacetype with multiple spaces
   //this is the issue with spaceloads if there are multiple spaces using a spaceload defined in a spaceType
@@ -2011,6 +2170,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuator_API_EMS) {
   std::vector<Lights> lights = model.getConcreteModelObjects<Lights>();
   std::vector<ElectricEquipment> electricEquipment = model.getConcreteModelObjects<ElectricEquipment>();
   std::vector<Space> spaces = model.getConcreteModelObjects<Space>();
+  std::sort(spaces.begin(), spaces.end(), WorkspaceObjectNameLess());
   std::vector<SpaceType> spaceTypes = model.getConcreteModelObjects<SpaceType>();
   std::vector<ThermalZone> thermalZone = model.getConcreteModelObjects<ThermalZone>();
 
@@ -2018,10 +2178,10 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuator_API_EMS) {
   auto thermalZone3 = thermalZone[0].clone(model).cast<ThermalZone>();
   auto thermalZone4 = thermalZone[0].clone(model).cast<ThermalZone>();
   //this will create 4 zones in a zonelist
-  spaces[0].setThermalZone(thermalZone[0]);
-  spaces[1].setThermalZone(thermalZone2);
-  spaces[2].setThermalZone(thermalZone3);
-  spaces[3].setThermalZone(thermalZone4);
+  spaces[0].setThermalZone(thermalZone[0]);  // Space 1
+  spaces[1].setThermalZone(thermalZone2);    // Space 2
+  spaces[2].setThermalZone(thermalZone3);    // Space 3
+  spaces[3].setThermalZone(thermalZone4);    // Space 4
   //This is the EDD file for the spaceload actuators for this model so far
   /*
 EnergyManagementSystem : Actuator Available, THERMAL ZONE 1 PEOPLE 1, People, Number of People, [each]
@@ -2039,126 +2199,81 @@ EnergyManagementSystem : Actuator Available, THERMAL ZONE 3 ELECTRIC EQUIPMENT 1
 EnergyManagementSystem : Actuator Available, THERMAL ZONE 4 ELECTRIC EQUIPMENT 1, ElectricEquipment, Electricity Rate, [W]
 */
 
+  // NOTE: here I'm setting one actuator to a Zone and one to a Space
   //actuator settings
   std::string lightsComponentType = "Lights";
   std::string lightsControlType = "Electricity Rate";
   //create actuator zone2
-  EnergyManagementSystemActuator lightsActuator2(lights[0], lightsComponentType, lightsControlType, spaces[2]);
+  EnergyManagementSystemActuator lightsActuator2(lights[0], lightsComponentType, lightsControlType, spaces[2].thermalZone().get());
   //EXPECT_EQ(lightsControlType, lightsActuator2.actuatedComponentControlType());
   //EXPECT_EQ(lightsComponentType, lightsActuator2.actuatedComponentType());
   //EXPECT_EQ(lights, lightsActuator2.actuatedComponent().get());
-  EXPECT_EQ(spaces[2].thermalZone().get().handle(), lightsActuator2.zoneName().get().handle());
+  EXPECT_EQ(spaces[2].thermalZone()->handle(), lightsActuator2.thermalZone().get().handle());
 
   //create actuator zone3
   EnergyManagementSystemActuator lightsActuator3(lights[0], lightsComponentType, lightsControlType, spaces[3]);
   //EXPECT_EQ(lightsControlType, lightsActuator3.actuatedComponentControlType());
   //EXPECT_EQ(lightsComponentType, lightsActuator3.actuatedComponentType());
   //EXPECT_EQ(lights, lightsActuator3.actuatedComponent().get());
-  EXPECT_EQ(spaces[3].thermalZone().get().handle(), lightsActuator3.zoneName().get().handle());
+  EXPECT_EQ(spaces[3].handle(), lightsActuator3.space().get().handle());
 
-  ForwardTranslator forwardTranslator;
-  Workspace workspace = forwardTranslator.translateModel(model);
-  EXPECT_TRUE(checkLogMessages(0, forwardTranslator.errors()));
-  //expect no warning since we are using the zoneName API
-  EXPECT_TRUE(checkLogMessages(0, forwardTranslator.warnings()));
-
-  //expect 2 actuators
-  EXPECT_EQ(2u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
-
-  std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator);
-  OptionalString name0 = objects[0].getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName);
-  OptionalString name1 = objects[1].getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName);
-  std::string test1 = "Thermal Zone 1 Lights 1";
-  std::string test2 = "Thermal Zone 2 Lights 1";
-  std::string test3 = "Thermal Zone 3 Lights 1";
-  std::string test4 = "Thermal Zone 4 Lights 1";
-  //EXPECT_EQ(name0.get(),test2);
-  //EXPECT_EQ(name1.get(), test1);
-  EXPECT_TRUE((name0.get() == test1) || (name0.get() == test2) || (name0.get() == test3) || (name0.get() == test4));
-  EXPECT_TRUE((name1.get() == test1) || (name1.get() == test2) || (name1.get() == test3) || (name1.get() == test4));
-  //model.save(toPath("./EMS_actuator_exampleModel2_electric.osm"), true);
-  //workspace.save(toPath("./EMS_actuator_exampleModel2_electric.idf"), true);
-}
-TEST_F(EnergyPlusFixture, ForwardTranslatorActuator_API2_EMS) {
-  //SAME AS PREVIOUS TEST BUT USE TZ instead of Spaces IN API
-  //use spacetype with multiple spaces
-  //this is the issue with spaceloads if there are multiple spaces using a spaceload defined in a spaceType
-  //the zonelist is created from the spaceType name, and the zones in the list are the space.thermalzone names
+  ForwardTranslator ft;
 
-  //Model model;
-  Model model = exampleModel();
-  auto oems = model.getUniqueModelObject<OutputEnergyManagementSystem>();
-  oems.setActuatorAvailabilityDictionaryReporting("Verbose");
+  // When excluding space translation (historical behavior)
+  {
+    ft.setExcludeSpaceTranslation(true);
 
-  std::vector<Lights> lights = model.getConcreteModelObjects<Lights>();
-  std::vector<ElectricEquipment> electricEquipment = model.getConcreteModelObjects<ElectricEquipment>();
-  std::vector<Space> spaces = model.getConcreteModelObjects<Space>();
-  std::vector<SpaceType> spaceTypes = model.getConcreteModelObjects<SpaceType>();
-  std::vector<ThermalZone> thermalZone = model.getConcreteModelObjects<ThermalZone>();
+    Workspace workspace = ft.translateModel(model);
 
-  auto thermalZone2 = thermalZone[0].clone(model).cast<ThermalZone>();
-  auto thermalZone3 = thermalZone[0].clone(model).cast<ThermalZone>();
-  auto thermalZone4 = thermalZone[0].clone(model).cast<ThermalZone>();
-  //this will create 4 zones in a zonelist
-  spaces[0].setThermalZone(thermalZone[0]);
-  spaces[1].setThermalZone(thermalZone2);
-  spaces[2].setThermalZone(thermalZone3);
-  spaces[3].setThermalZone(thermalZone4);
-  //This is the EDD file for the spaceload actuators for this model so far
-  /*
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 1 PEOPLE 1, People, Number of People, [each]
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 2 PEOPLE 1, People, Number of People, [each]
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 3 PEOPLE 1, People, Number of People, [each]
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 4 PEOPLE 1, People, Number of People, [each]
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 1 LIGHTS 1, Lights, Electricity Rate, [W]
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 2 LIGHTS 1, Lights, Electricity Rate, [W]
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 3 LIGHTS 1, Lights, Electricity Rate, [W]
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 4 LIGHTS 1, Lights, Electricity Rate, [W]
-  EnergyManagementSystem : Actuator Available, PRINTER, ElectricEquipment, Electricity Rate, [W]
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 1 ELECTRIC EQUIPMENT 1, ElectricEquipment, Electricity Rate, [W]
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 2 ELECTRIC EQUIPMENT 1, ElectricEquipment, Electricity Rate, [W]
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 3 ELECTRIC EQUIPMENT 1, ElectricEquipment, Electricity Rate, [W]
-  EnergyManagementSystem : Actuator Available, THERMAL ZONE 4 ELECTRIC EQUIPMENT 1, ElectricEquipment, Electricity Rate, [W]
-  */
+    // We get only a warning, since we can recover from it easily
+    EXPECT_EQ(0u, ft.errors().size());
+    EXPECT_EQ(1, ft.warnings().size());
+    EXPECT_EQ(
+      "Actuator 'Energy_Management_System_Actuator_2' references a SpaceLoad 'Lights 1' and specified that it wanted to be attached to the Space "
+      "'Space 4' but you have turned off ForwardTranslation's Space Feature. Falling back to using the attached ThermalZone 'Thermal Zone 4'.",
+      ft.warnings().front().logMessage());
 
-  //actuator settings
-  std::string lightsComponentType = "Lights";
-  std::string lightsControlType = "Electricity Rate";
-  //create actuator zone2
-  EnergyManagementSystemActuator lightsActuator2(lights[0], lightsComponentType, lightsControlType, thermalZone2);
-  //EXPECT_EQ(lightsControlType, lightsActuator2.actuatedComponentControlType());
-  //EXPECT_EQ(lightsComponentType, lightsActuator2.actuatedComponentType());
-  //EXPECT_EQ(lights, lightsActuator2.actuatedComponent().get());
-  EXPECT_EQ(spaces[1].thermalZone().get().handle(), lightsActuator2.zoneName().get().handle());
+    std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator);
+    //expect 2 actuators
+    ASSERT_EQ(2, objects.size());
 
-  //create actuator zone3
-  EnergyManagementSystemActuator lightsActuator3(lights[0], lightsComponentType, lightsControlType, thermalZone3);
-  //EXPECT_EQ(lightsControlType, lightsActuator3.actuatedComponentControlType());
-  //EXPECT_EQ(lightsComponentType, lightsActuator3.actuatedComponentType());
-  //EXPECT_EQ(lights, lightsActuator3.actuatedComponent().get());
-  EXPECT_EQ(spaces[2].thermalZone().get().handle(), lightsActuator3.zoneName().get().handle());
+    std::vector<std::string> actuatedNames;
+    std::transform(objects.cbegin(), objects.cend(), std::back_inserter(actuatedNames),
+                   [](const auto& wo) { return wo.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName).get(); });
+    std::sort(actuatedNames.begin(), actuatedNames.end());
 
-  ForwardTranslator forwardTranslator;
-  Workspace workspace = forwardTranslator.translateModel(model);
-  EXPECT_TRUE(checkLogMessages(0, forwardTranslator.errors()));
-  //expect no warning since we are using the zoneName API
-  EXPECT_TRUE(checkLogMessages(0, forwardTranslator.warnings()));
-  //expect 2 actuators
-  EXPECT_EQ(2u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
-
-  std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator);
-  OptionalString name0 = objects[0].getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName);
-  OptionalString name1 = objects[1].getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName);
-  std::string test1 = "Thermal Zone 1 Lights 1";
-  std::string test2 = "Thermal Zone 2 Lights 1";
-  std::string test3 = "Thermal Zone 3 Lights 1";
-  std::string test4 = "Thermal Zone 4 Lights 1";
-  //EXPECT_EQ(name0.get(),test2);
-  //EXPECT_EQ(name1.get(), test1);
-  EXPECT_TRUE((name0.get() == test1) || (name0.get() == test2) || (name0.get() == test3) || (name0.get() == test4));
-  EXPECT_TRUE((name1.get() == test1) || (name1.get() == test2) || (name1.get() == test3) || (name1.get() == test4));
-  //model.save(toPath("./EMS_actuator_exampleModel2_electric.osm"), true);
-  //workspace.save(toPath("./EMS_actuator_exampleModel2_electric.idf"), true);
+    EXPECT_EQ("Thermal Zone 3 Lights 1", actuatedNames.at(0));
+    EXPECT_EQ("Thermal Zone 4 Lights 1", actuatedNames.at(1));
+
+    //model.save(toPath("./EMS_actuator_exampleModel2_electric.osm"), true);
+    //workspace.save(toPath("./EMS_actuator_exampleModel2_electric.idf"), true);
+  }
+
+  // When including Space translation (new E+ 9.6.0)
+  {
+    ft.setExcludeSpaceTranslation(false);
+    Workspace workspace = ft.translateModel(model);
+
+    // We get only a warning, since we can recover from it easily
+    EXPECT_EQ(0u, ft.errors().size());
+    EXPECT_EQ(1, ft.warnings().size());
+    EXPECT_EQ("Actuator 'Energy_Management_System_Actuator_1' references a SpaceLoad 'Lights 1' and specified that it wanted to be attached to the "
+              "Thermal Zone 'Thermal Zone 3' but you have turned on ForwardTranslation's Space Feature. Falling back to using the attached Space "
+              "'Space 3' since there is only 1.",
+              ft.warnings().front().logMessage());
+
+    std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator);
+    //expect 2 actuators
+    ASSERT_EQ(2, objects.size());
+
+    std::vector<std::string> actuatedNames;
+    std::transform(objects.cbegin(), objects.cend(), std::back_inserter(actuatedNames),
+                   [](const auto& wo) { return wo.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName).get(); });
+    std::sort(actuatedNames.begin(), actuatedNames.end());
+
+    EXPECT_EQ("Space 3 Lights 1", actuatedNames.at(0));
+    EXPECT_EQ("Space 4 Lights 1", actuatedNames.at(1));
+  }
 }
 
 TEST_F(EnergyPlusFixture, ForwardTranslatorActuator_API3_EMS) {
@@ -2211,14 +2326,14 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuator_API3_EMS) {
   //EXPECT_EQ(lightsControlType, lightsActuator2.actuatedComponentControlType());
   //EXPECT_EQ(lightsComponentType, lightsActuator2.actuatedComponentType());
   //EXPECT_EQ(lights, lightsActuator2.actuatedComponent().get());
-  EXPECT_EQ(spaces[1].thermalZone().get().handle(), lightsActuator2.zoneName().get().handle());
+  EXPECT_EQ(spaces[1].thermalZone()->handle(), lightsActuator2.thermalZone()->handle());
 
   //create actuator zone3
   EnergyManagementSystemActuator lightsActuator3(lights[0], lightsComponentType, lightsControlType, thermalZone3);
   //EXPECT_EQ(lightsControlType, lightsActuator3.actuatedComponentControlType());
   //EXPECT_EQ(lightsComponentType, lightsActuator3.actuatedComponentType());
   //EXPECT_EQ(lights, lightsActuator3.actuatedComponent().get());
-  EXPECT_EQ(spaces[2].thermalZone().get().handle(), lightsActuator3.zoneName().get().handle());
+  EXPECT_EQ(spaces[2].thermalZone()->handle(), lightsActuator3.thermalZone()->handle());
 
   //this will create 4 zones in a zonelist
   spaces[0].setThermalZone(thermalZone[0]);
@@ -2230,32 +2345,80 @@ TEST_F(EnergyPlusFixture, ForwardTranslatorActuator_API3_EMS) {
   thermalZone3.remove();
   thermalZone4.remove();
 
-  ForwardTranslator forwardTranslator;
-  Workspace workspace = forwardTranslator.translateModel(model);
-  EXPECT_TRUE(checkLogMessages(0, forwardTranslator.errors()));
-  //expect no warning since we are using the zoneName API
-  EXPECT_TRUE(checkLogMessages(0, forwardTranslator.warnings(),
-                               {"Object of type 'OS:ThermalZone' and named 'Thermal Zone 1' has DaylightingControl Objects assigned. The interior "
-                                "walls between Spaces will be merged. Make sure these are correctly Matched!"}));
-
-  //expect 2 actuators
-  //ACTUATORS WILL STILL GET TRANSLATED WITH BLANK ZONENAME FIELD
-  EXPECT_EQ(2u, workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator).size());
-
-  std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator);
-  OptionalString name0 = objects[0].getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName);
-  OptionalString name1 = objects[1].getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName);
-  std::string test1 = "Thermal Zone 1 Lights 1";
-  std::string test2 = "Thermal Zone 2 Lights 1";
-  std::string test3 = "Thermal Zone 3 Lights 1";
-  std::string test4 = "Thermal Zone 4 Lights 1";
-  //ONLY 1 TZ in model now so should default back to that
-  EXPECT_EQ(name0.get(), test1);
-  EXPECT_EQ(name1.get(), test1);
-  //EXPECT_TRUE((name0.get() == test1) || (name0.get() == test2) || (name0.get() == test3) || (name0.get() == test4));
-  //EXPECT_TRUE((name1.get() == test1) || (name1.get() == test2) || (name1.get() == test3) || (name1.get() == test4));
-  //model.save(toPath("./EMS_actuator_exampleModel2_electric.osm"), true);
-  //workspace.save(toPath("./EMS_actuator_exampleModel2_electric.idf"), true);
+  ForwardTranslator ft;
+
+  // When excluding space translation (historical behavior)
+  {
+    ft.setExcludeSpaceTranslation(true);
+
+    Workspace workspace = ft.translateModel(model);
+
+    // We get only a warning, since we can recover from it easily
+    EXPECT_EQ(0u, ft.errors().size());
+    EXPECT_EQ(2, ft.warnings().size());
+    EXPECT_EQ(
+      "Actuator 'Energy_Management_System_Actuator_1' references a SpaceLoad 'Lights 1' attached to the SpaceType 'Space Type 1' but you have turned "
+      "off ForwardTranslation's Space Feature. Falling back to using the attached ThermalZone 'Thermal Zone 1' since there is only 1.",
+      ft.warnings().front().logMessage());
+    EXPECT_EQ(
+      "Actuator 'Energy_Management_System_Actuator_2' references a SpaceLoad 'Lights 1' attached to the SpaceType 'Space Type 1' but you have turned "
+      "off ForwardTranslation's Space Feature. Falling back to using the attached ThermalZone 'Thermal Zone 1' since there is only 1.",
+      ft.warnings().back().logMessage());
+
+    std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator);
+    //expect 2 actuators
+    //ACTUATORS WILL STILL GET TRANSLATED WITH BLANK ZONENAME FIELD
+    ASSERT_EQ(2, objects.size());
+
+    std::vector<std::string> actuatedNames;
+    std::transform(objects.cbegin(), objects.cend(), std::back_inserter(actuatedNames),
+                   [](const auto& wo) { return wo.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName).get(); });
+    std::sort(actuatedNames.begin(), actuatedNames.end());
+
+    // TODO: hum we end up with two actuators on the same zone, this is problematic... We did issue helpful warnings, and let E+ catch the issue.
+    // Can't always protect the user against themselves
+    EXPECT_EQ("Thermal Zone 1 Lights 1", actuatedNames.at(0));
+    EXPECT_EQ("Thermal Zone 1 Lights 1", actuatedNames.at(1));
+
+    //model.save(toPath("./EMS_actuator_exampleModel2_electric.osm"), true);
+    //workspace.save(toPath("./EMS_actuator_exampleModel2_electric.idf"), true);
+  }
+
+  // When including Space translation (new E+ 9.6.0)
+  {
+    ft.setExcludeSpaceTranslation(false);
+    Workspace workspace = ft.translateModel(model);
+
+    // We get only a warning, since we can recover from it easily
+    EXPECT_EQ(2, ft.errors().size());
+    EXPECT_EQ(
+      "Actuator 'Energy_Management_System_Actuator_1' references a SpaceLoad 'Lights 1' attached to the SpaceType 'Space Type 1' but you have turned "
+      "on ForwardTranslation's Space Feature. The Space Type has multiple spaces attached. Falling back to using the first Space 'Space 1'.",
+      ft.errors().front().logMessage());
+    EXPECT_EQ(
+      "Actuator 'Energy_Management_System_Actuator_2' references a SpaceLoad 'Lights 1' attached to the SpaceType 'Space Type 1' but you have turned "
+      "on ForwardTranslation's Space Feature. The Space Type has multiple spaces attached. Falling back to using the first Space 'Space 1'.",
+      ft.errors().back().logMessage());
+    EXPECT_EQ(1, ft.warnings().size());
+    EXPECT_EQ("Object of type 'OS:ThermalZone' and named 'Thermal Zone 1' has DaylightingControl Objects assigned. The interior walls between Spaces "
+              "will be merged. Make sure these are correctly Matched!",
+              ft.warnings().front().logMessage());
+
+    std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::EnergyManagementSystem_Actuator);
+    //expect 2 actuators
+    //ACTUATORS WILL STILL GET TRANSLATED WITH BLANK ZONENAME FIELD
+    ASSERT_EQ(2, objects.size());
+
+    std::vector<std::string> actuatedNames;
+    std::transform(objects.cbegin(), objects.cend(), std::back_inserter(actuatedNames),
+                   [](const auto& wo) { return wo.getString(EnergyManagementSystem_ActuatorFields::ActuatedComponentUniqueName).get(); });
+    std::sort(actuatedNames.begin(), actuatedNames.end());
+
+    // TODO: hum we end up with two actuators on the same zone, this is problematic... We did issue helpful warnings, and let E+ catch the issue.
+    // Can't always protect the user against themselves
+    EXPECT_EQ("Space 1 Lights 1", actuatedNames.at(0));
+    EXPECT_EQ("Space 1 Lights 1", actuatedNames.at(1));
+  }
 }
 
 TEST_F(EnergyPlusFixture, ReverseTranslatorProgramWeirdFormatting_EMS) {
diff --git a/src/model/EnergyManagementSystemActuator.cpp b/src/model/EnergyManagementSystemActuator.cpp
index d42b6667f48..30da990fb6e 100644
--- a/src/model/EnergyManagementSystemActuator.cpp
+++ b/src/model/EnergyManagementSystemActuator.cpp
@@ -36,6 +36,8 @@
 #include "ThermalZone_Impl.hpp"
 #include "Space.hpp"
 #include "Space_Impl.hpp"
+#include "SpaceLoadInstance.hpp"
+#include "SpaceLoadInstance_Impl.hpp"
 
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_EnergyManagementSystem_Actuator_FieldEnums.hxx>
@@ -80,15 +82,6 @@ namespace model {
       return result;
     }
 
-    boost::optional<ModelObject> EnergyManagementSystemActuator_Impl::zoneName() const {
-      boost::optional<ModelObject> result;
-      boost::optional<WorkspaceObject> wo = this->getTarget(OS_EnergyManagementSystem_ActuatorFields::ZoneName);
-      if (wo) {
-        result = wo->cast<ModelObject>();
-      }
-      return result;
-    }
-
     std::string EnergyManagementSystemActuator_Impl::actuatedComponentControlType() const {
       boost::optional<std::string> value = getString(OS_EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, true);
       if (value) {
@@ -108,51 +101,78 @@ namespace model {
     }
 
     bool EnergyManagementSystemActuator_Impl::setActuatedComponent(const ModelObject& modelObject) {
-      return setPointer(OS_EnergyManagementSystem_ActuatorFields::ActuatedComponentName, modelObject.handle());
-    }
-
-    bool EnergyManagementSystemActuator_Impl::setThermalZone(const ThermalZone& thermalZone) {
-      return setPointer(OS_EnergyManagementSystem_ActuatorFields::ZoneName, thermalZone.handle());
-    }
-
-    bool EnergyManagementSystemActuator_Impl::setSpace(const Space& space) {
-      //boost::optional<ThermalZone> tz;
-      auto tz = space.thermalZone();
-      if (tz) {
-        return setPointer(OS_EnergyManagementSystem_ActuatorFields::ZoneName, tz.get().handle());
-      } else {
-        LOG(Warn, "Warning, Space object" << space.briefDescription() << " does not have a ThermalZone object.")
-        return false;
+      if (!modelObject.optionalCast<SpaceLoadInstance>()) {
+        resetZoneOrSpace();
       }
+
+      return setPointer(OS_EnergyManagementSystem_ActuatorFields::ActuatedComponentName, modelObject.handle());
     }
 
     bool EnergyManagementSystemActuator_Impl::setActuatedComponentControlType(const std::string& actuatedComponentControlType) {
-      bool result = setString(OS_EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, actuatedComponentControlType);
+      const bool result = setString(OS_EnergyManagementSystem_ActuatorFields::ActuatedComponentControlType, actuatedComponentControlType);
       return result;
     }
 
     bool EnergyManagementSystemActuator_Impl::setActuatedComponentType(const std::string& actuatedComponentType) {
-      bool result = setString(OS_EnergyManagementSystem_ActuatorFields::ActuatedComponentType, actuatedComponentType);
+      const bool result = setString(OS_EnergyManagementSystem_ActuatorFields::ActuatedComponentType, actuatedComponentType);
       return result;
     }
 
-    void EnergyManagementSystemActuator_Impl::resetZoneName() {
-      bool result = setString(OS_EnergyManagementSystem_ActuatorFields::ZoneName, "");
+    boost::optional<ModelObject> EnergyManagementSystemActuator_Impl::zoneOrSpace() const {
+      return getObject<ModelObject>().getModelObjectTarget<ModelObject>(OS_EnergyManagementSystem_ActuatorFields::ZoneorSpaceName);
+    }
+
+    boost::optional<ThermalZone> EnergyManagementSystemActuator_Impl::thermalZone() const {
+      return getObject<ModelObject>().getModelObjectTarget<ThermalZone>(OS_EnergyManagementSystem_ActuatorFields::ZoneorSpaceName);
+    }
+
+    boost::optional<Space> EnergyManagementSystemActuator_Impl::space() const {
+      return getObject<ModelObject>().getModelObjectTarget<Space>(OS_EnergyManagementSystem_ActuatorFields::ZoneorSpaceName);
+    }
+
+    bool EnergyManagementSystemActuator_Impl::setThermalZone(const ThermalZone& thermalZone) {
+      if (auto comp_ = actuatedComponent()) {
+        if (comp_->optionalCast<SpaceLoadInstance>()) {
+          return setPointer(OS_EnergyManagementSystem_ActuatorFields::ZoneorSpaceName, thermalZone.handle());
+        }
+      }
+      LOG(Warn, "For " << briefDescription() << " cannot setThermalZone has it does not have an attached Component Type that is a SpaceLoadInstance");
+      return false;
+    }
+
+    bool EnergyManagementSystemActuator_Impl::setSpace(const Space& space) {
+      if (auto comp_ = actuatedComponent()) {
+        if (comp_->optionalCast<SpaceLoadInstance>()) {
+          return setPointer(OS_EnergyManagementSystem_ActuatorFields::ZoneorSpaceName, space.handle());
+        }
+      }
+      LOG(Warn, "For " << briefDescription() << " cannot setSpace has it does not have an attached Component Type that is a SpaceLoadInstance");
+      return false;
+    }
+
+    void EnergyManagementSystemActuator_Impl::resetZoneOrSpace() {
+      const bool result = setString(OS_EnergyManagementSystem_ActuatorFields::ZoneorSpaceName, "");
       OS_ASSERT(result);
     }
 
   }  // namespace detail
 
-  EnergyManagementSystemActuator::EnergyManagementSystemActuator(const ModelObject& modelObject, const std::string& actuatedComponentType,
+  EnergyManagementSystemActuator::EnergyManagementSystemActuator(const ModelObject& actuatedComponent, const std::string& actuatedComponentType,
                                                                  const std::string& actuatedComponentControlType)
-    : ModelObject(EnergyManagementSystemActuator::iddObjectType(), modelObject.model()) {
+    : ModelObject(EnergyManagementSystemActuator::iddObjectType(), actuatedComponent.model()) {
     OS_ASSERT(getImpl<detail::EnergyManagementSystemActuator_Impl>());
-    /** Do not use this constructor for spaceloads that are defined in SpaceType objects
-  **/
-    bool ok = setActuatedComponent(modelObject);
+    /** Do not use this constructor for spaceloads that are defined in SpaceType objects **/
+
+    if (actuatedComponent.optionalCast<SpaceLoadInstance>()) {
+      LOG(Warn, "When instantiating an EnergyManagementSystemActuator with an actuated component that is a SpaceLoadInstance, you should instead use "
+                "the overloaded constructor that takes a Space (or a ThermalZone if you plan on disabling the Space Feature during "
+                "ForwardTranslation) as the last parameter");
+    }
+
+    bool ok = setActuatedComponent(actuatedComponent);
     if (!ok) {
       remove();
-      LOG_AND_THROW("Unable to set " << briefDescription() << "'s setActuatedComponent to " << modelObject.briefDescription() << ".");
+      LOG_AND_THROW("Unable to set " << briefDescription() << "'s setActuatedComponent to " << actuatedComponent.briefDescription() << ".");
     }
     ok = setActuatedComponentType(actuatedComponentType);
     if (!ok) {
@@ -166,17 +186,25 @@ namespace model {
     }
   }
 
-  EnergyManagementSystemActuator::EnergyManagementSystemActuator(const ModelObject& modelObject, const std::string& actuatedComponentType,
+  EnergyManagementSystemActuator::EnergyManagementSystemActuator(const ModelObject& actuatedComponent, const std::string& actuatedComponentType,
                                                                  const std::string& actuatedComponentControlType, const ThermalZone& thermalZone)
-    : ModelObject(EnergyManagementSystemActuator::iddObjectType(), modelObject.model()) {
+    : ModelObject(EnergyManagementSystemActuator::iddObjectType(), actuatedComponent.model()) {
     OS_ASSERT(getImpl<detail::EnergyManagementSystemActuator_Impl>());
     /** This constructor uses the ThermalZone as the ZoneName field
-      * This is what is expected in E+ for spaceloads in OS that are defined in SpaceTypes and used in Spaces
-  **/
-    bool ok = setActuatedComponent(modelObject);
+      * This is what is expected in E+ for spaceloads in OS that are defined in SpaceTypes and used in Spaces **/
+
+    if (!actuatedComponent.optionalCast<SpaceLoadInstance>()) {
+      remove();
+      LOG_AND_THROW("When using this overloaded EnergyManagementSystemActuator constructor that takes a ThermalZone as the last parameter, the "
+                    "actuated component must be "
+                    "a SpaceLoadInstance, but you supplied "
+                    << actuatedComponent.briefDescription());
+    }
+
+    bool ok = setActuatedComponent(actuatedComponent);
     if (!ok) {
       remove();
-      LOG_AND_THROW("Unable to set " << briefDescription() << "'s setActuatedComponent to " << modelObject.briefDescription() << ".");
+      LOG_AND_THROW("Unable to set " << briefDescription() << "'s setActuatedComponent to " << actuatedComponent.briefDescription() << ".");
     }
     ok = setActuatedComponentType(actuatedComponentType);
     if (!ok) {
@@ -197,15 +225,23 @@ namespace model {
     }
   }
 
-  EnergyManagementSystemActuator::EnergyManagementSystemActuator(const ModelObject& modelObject, const std::string& actuatedComponentType,
+  EnergyManagementSystemActuator::EnergyManagementSystemActuator(const ModelObject& actuatedComponent, const std::string& actuatedComponentType,
                                                                  const std::string& actuatedComponentControlType, const Space& space)
-    : ModelObject(EnergyManagementSystemActuator::iddObjectType(), modelObject.model()) {
+    : ModelObject(EnergyManagementSystemActuator::iddObjectType(), actuatedComponent.model()) {
     OS_ASSERT(getImpl<detail::EnergyManagementSystemActuator_Impl>());
-    //This constructor takes the Space and uses the ThermalZone of the Space as the ZoneName
-    bool ok = setActuatedComponent(modelObject);
+
+    if (!actuatedComponent.optionalCast<SpaceLoadInstance>()) {
+      remove();
+      LOG_AND_THROW("When using this overloaded EnergyManagementSystemActuator constructor that takes a Space as the last parameter, the actuated "
+                    "component must be "
+                    "a SpaceLoadInstance, but you supplied "
+                    << actuatedComponent.briefDescription());
+    }
+
+    bool ok = setActuatedComponent(actuatedComponent);
     if (!ok) {
       remove();
-      LOG_AND_THROW("Unable to set " << briefDescription() << "'s setActuatedComponent to " << modelObject.briefDescription() << ".");
+      LOG_AND_THROW("Unable to set " << briefDescription() << "'s setActuatedComponent to " << actuatedComponent.briefDescription() << ".");
     }
     ok = setActuatedComponentType(actuatedComponentType);
     if (!ok) {
@@ -226,11 +262,11 @@ namespace model {
     }
   }
 
-  EnergyManagementSystemActuator::EnergyManagementSystemActuator(const ModelObject& modelObject)
-    : ModelObject(EnergyManagementSystemActuator::iddObjectType(), modelObject.model()) {
+  EnergyManagementSystemActuator::EnergyManagementSystemActuator(const ModelObject& actuatedComponent)
+    : ModelObject(EnergyManagementSystemActuator::iddObjectType(), actuatedComponent.model()) {
     OS_ASSERT(getImpl<detail::EnergyManagementSystemActuator_Impl>());
-    setActuatedComponent(modelObject);
-    //TODO set below to some appropriate default that depends on the modelObject::IddType
+    setActuatedComponent(actuatedComponent);
+    //TODO set below to some appropriate default that depends on the actuatedComponent::IddType
     //setActuatedComponentControlType();
     //setActuatedComponentType();
   }
@@ -240,8 +276,8 @@ namespace model {
     OS_ASSERT(getImpl<detail::EnergyManagementSystemActuator_Impl>());
     //This constructor is used in the ReverseTranslator when the ActuatedComponent doesnt Reverse Translate.
     //In that case, a generic Actuator is created with ActuatedComponent blank (but the old value is in a comment)
-    //TODO setActuatedComponent to a default modelObject.
-    //TODO set below to some appropriate default that depends on the modelObject::IddType
+    //TODO setActuatedComponent to a default actuatedComponent.
+    //TODO set below to some appropriate default that depends on the actuatedComponent::IddType
     //setActuatedComponentControlType();
     //setActuatedComponentType();
   }
@@ -254,10 +290,6 @@ namespace model {
     return getImpl<detail::EnergyManagementSystemActuator_Impl>()->actuatedComponent();
   }
 
-  boost::optional<ModelObject> EnergyManagementSystemActuator::zoneName() const {
-    return getImpl<detail::EnergyManagementSystemActuator_Impl>()->zoneName();
-  }
-
   std::string EnergyManagementSystemActuator::actuatedComponentControlType() const {
     return getImpl<detail::EnergyManagementSystemActuator_Impl>()->actuatedComponentControlType();
   }
@@ -270,6 +302,26 @@ namespace model {
     return getImpl<detail::EnergyManagementSystemActuator_Impl>()->setActuatedComponent(modelObject);
   }
 
+  bool EnergyManagementSystemActuator::setActuatedComponentControlType(const std::string& actuatedComponentControlType) {
+    return getImpl<detail::EnergyManagementSystemActuator_Impl>()->setActuatedComponentControlType(actuatedComponentControlType);
+  }
+
+  bool EnergyManagementSystemActuator::setActuatedComponentType(const std::string& actuatedComponentType) {
+    return getImpl<detail::EnergyManagementSystemActuator_Impl>()->setActuatedComponentType(actuatedComponentType);
+  }
+
+  boost::optional<Space> EnergyManagementSystemActuator::space() const {
+    return getImpl<detail::EnergyManagementSystemActuator_Impl>()->space();
+  }
+
+  boost::optional<ThermalZone> EnergyManagementSystemActuator::thermalZone() const {
+    return getImpl<detail::EnergyManagementSystemActuator_Impl>()->thermalZone();
+  }
+
+  boost::optional<ModelObject> EnergyManagementSystemActuator::zoneOrSpace() const {
+    return getImpl<detail::EnergyManagementSystemActuator_Impl>()->zoneOrSpace();
+  }
+
   bool EnergyManagementSystemActuator::setThermalZone(const ThermalZone& thermalZone) {
     return getImpl<detail::EnergyManagementSystemActuator_Impl>()->setThermalZone(thermalZone);
   }
@@ -278,21 +330,27 @@ namespace model {
     return getImpl<detail::EnergyManagementSystemActuator_Impl>()->setSpace(space);
   }
 
-  bool EnergyManagementSystemActuator::setActuatedComponentControlType(const std::string& actuatedComponentControlType) {
-    return getImpl<detail::EnergyManagementSystemActuator_Impl>()->setActuatedComponentControlType(actuatedComponentControlType);
+  void EnergyManagementSystemActuator::resetZoneOrSpace() {
+    getImpl<detail::EnergyManagementSystemActuator_Impl>()->resetZoneOrSpace();
   }
 
-  bool EnergyManagementSystemActuator::setActuatedComponentType(const std::string& actuatedComponentType) {
-    return getImpl<detail::EnergyManagementSystemActuator_Impl>()->setActuatedComponentType(actuatedComponentType);
+  /// @cond
+  EnergyManagementSystemActuator::EnergyManagementSystemActuator(std::shared_ptr<detail::EnergyManagementSystemActuator_Impl> impl)
+    : ModelObject(std::move(impl)) {}
+
+  // DEPRECATED
+
+  boost::optional<ModelObject> EnergyManagementSystemActuator::zoneName() const {
+    LOG(Warn, "As of 3.6.0, EnergyManagementSystemActuator::zoneName is deprecated. Use zoneOrSpace instead. "
+              "It will be removed within three releases.");
+    return getImpl<detail::EnergyManagementSystemActuator_Impl>()->zoneOrSpace();
   }
 
   void EnergyManagementSystemActuator::resetZoneName() {
-    getImpl<detail::EnergyManagementSystemActuator_Impl>()->resetZoneName();
+    LOG(Warn, "As of 3.6.0, EnergyManagementSystemActuator::resetZoneName is deprecated. Use resetZoneOrSpace instead. "
+              "It will be removed within three releases.");
+    getImpl<detail::EnergyManagementSystemActuator_Impl>()->resetZoneOrSpace();
   }
-
-  /// @cond
-  EnergyManagementSystemActuator::EnergyManagementSystemActuator(std::shared_ptr<detail::EnergyManagementSystemActuator_Impl> impl)
-    : ModelObject(std::move(impl)) {}
   /// @endcond
 
 }  // namespace model
diff --git a/src/model/EnergyManagementSystemActuator.hpp b/src/model/EnergyManagementSystemActuator.hpp
index 5ef7b5f5e6a..7fcb0af25f3 100644
--- a/src/model/EnergyManagementSystemActuator.hpp
+++ b/src/model/EnergyManagementSystemActuator.hpp
@@ -33,6 +33,8 @@
 #include "ModelAPI.hpp"
 #include "ModelObject.hpp"
 
+#include "../utilities/core/Deprecated.hpp"
+
 namespace openstudio {
 
 namespace energyplus {
@@ -57,20 +59,27 @@ namespace model {
     /** @name Constructors and Destructors */
     //@{
 
-    explicit EnergyManagementSystemActuator(const ModelObject& modelObject, const std::string& actuatedComponentType,
+    /** Constructor to use for any actuated component that is not a SpaceLoadInstance */
+    explicit EnergyManagementSystemActuator(const ModelObject& actuatedComponent, const std::string& actuatedComponentType,
                                             const std::string& actuatedComponentControlType);
     /**These constructors below are for SpaceloadInstances that are defined in SpaceTypes that are used in Spaces.
      * Upon translation, the SpaceLoadInstances use ZoneLists which are not avail in OS
      * The ZoneListName is the SpaceType name
      * The Zone's are the Space->ThermalZone names
-     * So to attach to a future zone, use the TZ or the Space that the SpaceLoadInstance will operate on
-  **/
-    explicit EnergyManagementSystemActuator(const ModelObject& modelObject, const std::string& actuatedComponentType,
-                                            const std::string& actuatedComponentControlType, const ThermalZone& thermalZone);
+     * So to attach to a future zone, use the TZ or the Space that the SpaceLoadInstance will operate on **/
 
-    explicit EnergyManagementSystemActuator(const ModelObject& modelObject, const std::string& actuatedComponentType,
+    // TODO: the first parameter should be a SpaceLoadInstance, not a ModelObject
+    /** Constructor that will only accept a SpaceLoadInstance as the actuated component. Use this version if do not plan on disabling the Space
+     * Translation in the Forward Translator */
+    explicit EnergyManagementSystemActuator(const ModelObject& actuatedComponent, const std::string& actuatedComponentType,
                                             const std::string& actuatedComponentControlType, const Space& space);
 
+    // TODO: the first parameter should be a SpaceLoadInstance, not a ModelObject
+    /** Constructor that will only accept a SpaceLoadInstance as the actuated component. Use this version if you plan on disabling the Space
+     * Translation in the Forward Translator */
+    explicit EnergyManagementSystemActuator(const ModelObject& actuatedComponent, const std::string& actuatedComponentType,
+                                            const std::string& actuatedComponentControlType, const ThermalZone& thermalZone);
+
     virtual ~EnergyManagementSystemActuator() = default;
     // Default the copy and move operators because the virtual dtor is explicit
     EnergyManagementSystemActuator(const EnergyManagementSystemActuator& other) = default;
@@ -85,13 +94,17 @@ namespace model {
     /** @name Getters */
     //@{
 
-    boost::optional<ModelObject> actuatedComponent() const;
+    boost::optional<ModelObject> actuatedComponent() const;  // TODO: this should NOT be an optional
 
     std::string actuatedComponentControlType() const;
 
     std::string actuatedComponentType() const;
 
-    boost::optional<ModelObject> zoneName() const;
+    OS_DEPRECATED boost::optional<ModelObject> zoneName() const;
+
+    boost::optional<ModelObject> zoneOrSpace() const;
+    boost::optional<ThermalZone> thermalZone() const;
+    boost::optional<Space> space() const;
 
     //@}
     /** @name Setters */
@@ -107,7 +120,8 @@ namespace model {
     //set the ZoneName field to the Space's ThermalZone's name
     bool setSpace(const Space& space);
 
-    void resetZoneName();
+    OS_DEPRECATED void resetZoneName();
+    void resetZoneOrSpace();
 
     //@}
     /** @name Other */
@@ -124,14 +138,16 @@ namespace model {
     friend class Model;
     friend class IdfObject;
     friend class openstudio::detail::IdfObject_Impl;
+
+    // These are for the ReverseTranslator
+    explicit EnergyManagementSystemActuator(const ModelObject& actuatedComponent);
+
+    explicit EnergyManagementSystemActuator(const Model& model);
+
     friend class energyplus::ReverseTranslator;
     /// @endcond
    private:
     REGISTER_LOGGER("openstudio.model.EnergyManagementSystemActuator");
-    //These are for the ReveseTranslator
-    explicit EnergyManagementSystemActuator(const ModelObject& modelObject);
-
-    explicit EnergyManagementSystemActuator(const Model& model);
   };
 
   /** \relates EnergyManagementSystemActuator*/
diff --git a/src/model/EnergyManagementSystemActuator_Impl.hpp b/src/model/EnergyManagementSystemActuator_Impl.hpp
index fa4938ba6cc..029df235a0b 100644
--- a/src/model/EnergyManagementSystemActuator_Impl.hpp
+++ b/src/model/EnergyManagementSystemActuator_Impl.hpp
@@ -74,7 +74,9 @@ namespace model {
 
       std::string actuatedComponentType() const;
 
-      boost::optional<ModelObject> zoneName() const;
+      boost::optional<ModelObject> zoneOrSpace() const;
+      boost::optional<ThermalZone> thermalZone() const;
+      boost::optional<Space> space() const;
 
       //@}
       /** @name Setters */
@@ -87,10 +89,8 @@ namespace model {
       bool setActuatedComponentType(const std::string& actuatedComponentType);
 
       bool setThermalZone(const ThermalZone& thermalZone);
-
       bool setSpace(const Space& space);
-
-      void resetZoneName();
+      void resetZoneOrSpace();
 
       //@}
       /** @name Other */


Test patch:
diff --git a/src/model/test/EnergyManagementSystemActuator_GTest.cpp b/src/model/test/EnergyManagementSystemActuator_GTest.cpp
index 7ca8c6a09e6..3724e5c7430 100644
--- a/src/model/test/EnergyManagementSystemActuator_GTest.cpp
+++ b/src/model/test/EnergyManagementSystemActuator_GTest.cpp
@@ -216,14 +216,16 @@ TEST_F(ModelFixture, EMSActuator_newEMSActuator2) {
   EXPECT_EQ(lightsControlType, lightsActuator2.actuatedComponentControlType());
   EXPECT_EQ(lightsComponentType, lightsActuator2.actuatedComponentType());
   EXPECT_EQ(lights, lightsActuator2.actuatedComponent().get());
-  EXPECT_EQ(zone2.handle(), lightsActuator2.zoneName().get().handle());
+  ASSERT_TRUE(lightsActuator2.zoneOrSpace());
+  EXPECT_EQ(zone2.handle(), lightsActuator2.zoneOrSpace()->handle());
 
   //create actuator zone3
   EnergyManagementSystemActuator lightsActuator3(lights, lightsComponentType, lightsControlType, zone2);
   EXPECT_EQ(lightsControlType, lightsActuator3.actuatedComponentControlType());
   EXPECT_EQ(lightsComponentType, lightsActuator3.actuatedComponentType());
   EXPECT_EQ(lights, lightsActuator3.actuatedComponent().get());
-  EXPECT_EQ(zone2.handle(), lightsActuator3.zoneName().get().handle());
+  ASSERT_TRUE(lightsActuator3.zoneOrSpace());
+  EXPECT_EQ(zone2.handle(), lightsActuator3.zoneOrSpace()->handle());
 }
 
 TEST_F(ModelFixture, EMSActuator_newEMSActuator3) {
@@ -259,12 +261,99 @@ TEST_F(ModelFixture, EMSActuator_newEMSActuator3) {
   EXPECT_EQ(lightsControlType, lightsActuator2.actuatedComponentControlType());
   EXPECT_EQ(lightsComponentType, lightsActuator2.actuatedComponentType());
   EXPECT_EQ(lights, lightsActuator2.actuatedComponent().get());
-  EXPECT_EQ(space2.thermalZone().get().handle(), lightsActuator2.zoneName().get().handle());
+  ASSERT_TRUE(lightsActuator2.zoneOrSpace());
+  EXPECT_EQ(space2.handle(), lightsActuator2.zoneOrSpace()->handle());
 
   //create actuator zone3
   EnergyManagementSystemActuator lightsActuator3(lights, lightsComponentType, lightsControlType, space3);
   EXPECT_EQ(lightsControlType, lightsActuator3.actuatedComponentControlType());
   EXPECT_EQ(lightsComponentType, lightsActuator3.actuatedComponentType());
-  EXPECT_EQ(lights, lightsActuator3.actuatedComponent().get());
-  EXPECT_EQ(space3.thermalZone().get().handle(), lightsActuator3.zoneName().get().handle());
+  ASSERT_TRUE(lightsActuator3.zoneOrSpace());
+  EXPECT_EQ(space3.handle(), lightsActuator3.zoneOrSpace()->handle());
+}
+
+TEST_F(ModelFixture, EMSActuator_SpaceLoad_EnforceZoneOrSpace) {
+  //USE spaces in constructor
+  Model model;
+
+  //use spacetype with multiple spaces
+  //this is the issue with spaceloads if there are multiple spaces using a spaceload defined in a spaceType
+  //the zonelist is created from the spaceType name, and the zones in the list are the space.thermalzone names
+  SpaceType spaceType(model);
+  Space space(model);
+  ThermalZone zone(model);
+  space.setSpaceType(spaceType);
+  space.setThermalZone(zone);
+
+  Building building = model.getUniqueModelObject<Building>();
+
+  //add lights and attach to spaceType
+  LightsDefinition lightsDefinition(model);
+  lightsDefinition.setWattsperSpaceFloorArea(1.0);
+  Lights lights(lightsDefinition);
+  //add lights to spaceType which space2 and space3 use
+  lights.setSpaceType(spaceType);
+
+  ElectricEquipmentDefinition electricEquipmentDefinition(model);
+  ElectricEquipment electricEquipment(electricEquipmentDefinition);
+
+  // actuator settings
+  const std::string lightsComponentType = "Lights";
+  const std::string lightsControlType = "Electricity Rate";
+
+  // If passing a Space or ThermalZone, we throw if the actuated component is not a SpaceLoadInstance
+  EXPECT_ANY_THROW(EnergyManagementSystemActuator(building, lightsComponentType, lightsControlType, space));
+  EXPECT_ANY_THROW(EnergyManagementSystemActuator(building, lightsComponentType, lightsControlType, zone));
+  EXPECT_ANY_THROW(EnergyManagementSystemActuator(lightsDefinition, lightsComponentType, lightsControlType, space));
+  EXPECT_ANY_THROW(EnergyManagementSystemActuator(lightsDefinition, lightsComponentType, lightsControlType, zone));
+
+  {
+    EnergyManagementSystemActuator lightsActuator(lights, lightsComponentType, lightsControlType, space);
+    EXPECT_EQ(lights, lightsActuator.actuatedComponent().get());
+    EXPECT_EQ(lightsControlType, lightsActuator.actuatedComponentControlType());
+    EXPECT_EQ(lightsComponentType, lightsActuator.actuatedComponentType());
+    ASSERT_TRUE(lightsActuator.zoneOrSpace());
+    ASSERT_TRUE(lightsActuator.space());
+    EXPECT_FALSE(lightsActuator.thermalZone());
+    EXPECT_EQ(space.handle(), lightsActuator.zoneOrSpace()->handle());
+    EXPECT_EQ(space.handle(), lightsActuator.space()->handle());
+
+    // Setting to something that is a SpaceLoadInstance doesn't reset the ZoneOrSpace, but any other type does
+    EXPECT_TRUE(lightsActuator.setActuatedComponent(electricEquipment));
+    ASSERT_TRUE(lightsActuator.zoneOrSpace());
+    ASSERT_TRUE(lightsActuator.space());
+    EXPECT_FALSE(lightsActuator.thermalZone());
+    EXPECT_EQ(space.handle(), lightsActuator.zoneOrSpace()->handle());
+    EXPECT_EQ(space.handle(), lightsActuator.space()->handle());
+
+    EXPECT_TRUE(lightsActuator.setActuatedComponent(building));
+    EXPECT_FALSE(lightsActuator.zoneOrSpace());
+    EXPECT_FALSE(lightsActuator.space());
+    EXPECT_FALSE(lightsActuator.thermalZone());
+  }
+
+  {
+    EnergyManagementSystemActuator lightsActuator(lights, lightsComponentType, lightsControlType, zone);
+    EXPECT_EQ(lights, lightsActuator.actuatedComponent().get());
+    EXPECT_EQ(lightsControlType, lightsActuator.actuatedComponentControlType());
+    EXPECT_EQ(lightsComponentType, lightsActuator.actuatedComponentType());
+    ASSERT_TRUE(lightsActuator.zoneOrSpace());
+    EXPECT_FALSE(lightsActuator.space());
+    ASSERT_TRUE(lightsActuator.thermalZone());
+    EXPECT_EQ(zone.handle(), lightsActuator.zoneOrSpace()->handle());
+    EXPECT_EQ(zone.handle(), lightsActuator.thermalZone()->handle());
+
+    // Setting to something that is a SpaceLoadInstance doesn't reset the ZoneOrSpace, but any other type does
+    EXPECT_TRUE(lightsActuator.setActuatedComponent(electricEquipment));
+    ASSERT_TRUE(lightsActuator.zoneOrSpace());
+    EXPECT_FALSE(lightsActuator.space());
+    ASSERT_TRUE(lightsActuator.thermalZone());
+    EXPECT_EQ(zone.handle(), lightsActuator.zoneOrSpace()->handle());
+    EXPECT_EQ(zone.handle(), lightsActuator.thermalZone()->handle());
+
+    EXPECT_TRUE(lightsActuator.setActuatedComponent(building));
+    EXPECT_FALSE(lightsActuator.zoneOrSpace());
+    EXPECT_FALSE(lightsActuator.space());
+    EXPECT_FALSE(lightsActuator.thermalZone());
+  }
 }