#directive   on FIELD
#directive  on FIELD
directive  @aws_subscribe(mutations: String!) on FIELD_DEFINITION

schema {
    query: Query
    mutation: Mutation
    subscription: Subscription
}

type Query {
    alarms(homeId: ID!): AlarmCollection
    area(areaId: ID!): Area
    cloudConnections(homeId: ID!): CloudConnectionCollection
    device(deviceId: ID!): Device
    deviceIdentifyBySerialNumber(serialNumber: String!): DeviceIdentifyPayload
    deviceIdentifyByQRCode(qrCode: String!): DeviceIdentifyPayload
    deviceManufacturers: [DeviceManufacturer!]!
    deviceTemplates(manufacturerId: ID, deviceType: DeviceType, language: String): [DeviceTemplate!]!
    statsEnergySummary(homeId: ID!): EnergyStatsSummaryPayload
    statsTimeSeries(select: [TimeSeriesSelectInput!]!, scope: StatsScopeInput!): TimeSeriesPayload
    home(homeId: ID!): Home
    homes(sort: HomeSortInput): [Home!]!
    homeMemberInvitations(homeId: ID!): HomeMemberInvitationCollection
    homeMemberInvitation(homeMemberInvitationId: ID!, token: String!): InvitedUserHomeMemberInvitation
    homeMember(homeMemberId: ID!): HomeMember
    homeMembers(homeId: ID!): HomeMemberCollection

    hubIdentifyByMacAddress(macAddress: String!): HubIdentifyPayload
    hubIdentifyBySerialNumber(serialNumber: String!): HubIdentifyPayload
    hubIdentifyByQrCode(qrCode: String!): HubIdentifyPayload
    hubGetDppPayload(hubId: String!, homeKitSetupPayload: String!): HubGetDppPayload!
    hubTemplates: [HubTemplate!]!
    hubScanFoundDevices(commandId: ID!): [HubScanFoundDevice!]!
    homeHubsCollectiveAlarm(homeId: ID!, alarmType: AlarmType!): [HubCollectiveAlarm!]!

    userMyAccount: Account
    userPreferences: AccountPreferences
    notificationsInbox: InboxNotificationCollection
    insuranceCompanies(homeId: ID!): InsuranceCompanyCollection

    # internal
    userAccount(userId: ID!): Account
    userAccountByEmail(email: String!): Account
    invitedUserHome(homeId: ID!): InvitedUserHome

    # to be implemented
    homeOrganizations(homeId: ID!): [Organization!]!
    deviceAccessPolicyForUser(deviceId: ID!, userId: ID!): DeviceAccessPolicy
    deviceUsersWithAccess(deviceId: ID!): [HomeMember!]!
    areaAccessPoliciesForUser(areaId: ID!, userId: ID!): [HomeProfileActionAccess!]!
    areaUsersWithAccess(areaId: ID!): [HomeMember!]!

    installerDashboard: InstallerDashboard
    installerProject(projectId: ID!): Project
    installerProjects: InstallerProjectCollection

    emergencyContact(emergencyContactId: ID!): EmergencyContact
    emergencyContacts(homeId: ID!): EmergencyContactCollection

    alarmStationInfo(homeId: ID!): AlarmStationInfo

    # devices
    command(commandId: ID!): Command

    # device groups
    deviceGroups(homeId: ID!): DeviceGroupCollection

    # freeze protection
    freezeProtection(homeId: ID!): FreezeProtection

    # smart charge hooks - current API
    smartChargeUserSync: SmartChargeUserSyncPayload

    # device firmware management
    deviceFirmwareUploadUrl(
        model: String!,
        version: String!,
        transportMedium: DeviceFirmwareTransportMedium!,
        variant: DeviceFirmwareVariant
    ): String

    # routines
    routines(homeId: ID!): RoutineCollection
    routine(routineId: ID!): Routine

    # demand response
    demandResponse: DemandResponse

    # smart energy
    smartEnergy(homeId: ID!): SmartEnergy

    # housing associations
    housingAssociation(housingAssociationId: ID!): HousingAssociation

    # collective alarms
    collectiveAlarms(homeId: ID!): CollectiveAlarmCollection

    # Geofence Safeboat
    getGeofenceStatus(homeId: ID!): GeofenceStatus
}

type Mutation {
    # Requests alarms in `ALARM` or `SNOOZED` state to transition to a `CLEARED` or `SNOOZED` state
    # depending on current sensors state. For the end result of this action clients need to wait
    # for the `alarmUpdated` subscription to trigger, meaning until the subscription fires this
    # action is in a pending state.
    alarmResolve(alarmId: ID!, snoozeDurationSeconds: Int): AlarmResolvePayload  # @GuidedTour("AppSyncEvent", 1)
    alarmSetArm(alarmId: ID!, isArmed: Boolean!): AlarmSetArmPayload
    alarmAcknowledge(alarmId: ID!): AlarmAcknowledgePayload
    alarmAlertEmergencyContactsNotificationRequest(alarmNotificationLifecycleId: ID!): AlarmAlertEmergencyContactsNotificationRequestPayload
    alarmAlertEmergencyContactsNotificationDismiss(alarmNotificationLifecycleId: ID!): AlarmAlertEmergencyContactsNotificationDismissPayload
    alarmImOkEmergencyContactsNotificationRequest(alarmNotificationLifecycleId: ID!): AlarmImOkEmergencyContactsNotificationRequestPayload
    alarmImOkEmergencyContactsNotificationDismiss(alarmNotificationLifecycleId: ID!): AlarmImOkEmergencyContactsNotificationDismissPayload

    areaAddDevice(areaId: ID!, deviceId: ID!): AreaAddDevicePayload
    areaCreate(homeId: ID!, data: AreaCreateInput!): AreaCreatePayload
    areaDelete(areaId: ID!): AreaDeletePayload
    areaRemoveDevice(areaId: ID!, deviceId: ID!): AreaRemoveDevicePayload
    areaUpdate(areaId: ID!, data: AreaUpdateInput!): AreaUpdatePayload
    areaAddHub(areaId: ID!, hubId: ID!): AreaAddHubPayload
    areaRemoveHub(areaId: ID!, hubId: ID!): AreaRemoveHubPayload

    # Cloud connections
    cloudConnectionDisconnect(homeId: ID!, providerId: ID!): CloudConnectionDisconnectPayload
    # It should be invoked once the user grants Abra access to provided energy meter
    # and Abra can start checking if the access has been successfully granted.
    # homeUpdated subscription will be triggered once Abra confirms
    # the access has been granted (see CloudConnectionUpdatedPayload).
    cloudConnectionElhubConnect(homeId: ID!, energyMeterIds: [String!]!): ElhubConnectPayload

    deviceRegisterByQrCode(homeId: ID!, qrCode: String!): DeviceRegisterByQrCodePayload
    deviceUnregister(deviceId: ID!): DeviceUnregisterPayload
    deviceUnregisterV2(deviceId: ID!): DeviceUnregisterV2Payload
    deviceSetRelayDeviceType(deviceId: ID!, deviceType: DeviceType): DeviceSetRelayDeviceTypePayload
    deviceSetIoModuleConfiguration(deviceId: ID!, configuration: IoModuleConfiguration): DeviceSetIoModuleConfigurationPayload

    deviceSetArmed(deviceId: ID!, isArmed: Boolean!, disarmTimeout: Int, commandSource: CommandSource): DeviceSetArmedPayload
    deviceSetBrightness(deviceId: ID!, brightness: Float!, commandSource: CommandSource): DeviceSetBrightnessPayload
    deviceSetColor(deviceId: ID!, color: DeviceSetColorInput!, commandSource: CommandSource): DeviceSetColorPayload
    deviceSetOnOff(deviceId: ID!, isOn: Boolean!, commandSource: CommandSource): DeviceSetOnOffPayload
    deviceSetOpenPercent(deviceId: ID!, openPercent: Float!, commandSource: CommandSource): DeviceSetOpenPercentPayload
    deviceSetUnlocked(deviceId: ID!, isUnlocked: Boolean!, commandSource: CommandSource): DeviceSetUnlockedPayload
    deviceSetChildLock(deviceId: ID!, childLock: Boolean!, commandSource: CommandSource): DeviceSetChildLockPayload
    deviceSetTemperatureSetpoint(deviceId: ID!, delta: Float!, commandSource: CommandSource): DeviceSetTemperatureSetpointPayload
    deviceSetTemperatureSetpointPercentage(deviceId: ID!, delta: Float!, commandSource: CommandSource): DeviceSetTemperatureSetpointPercentagePayload
    deviceSetTemperature(deviceId: ID!, temperature: Float!, commandSource: CommandSource): DeviceSetTemperaturePayload
    deviceSetTemperaturePercentage(deviceId: ID!, temperature: Float!, commandSource: CommandSource): DeviceSetTemperaturePercentagePayload
    deviceSetClimateMode(deviceId: ID!, climateMode: ClimateMode!, commandSource: CommandSource): DeviceSetClimateModePayload
    deviceSetMaximumFloorTemperature(deviceId: ID!, maximumFloorTemperature: Float!, commandSource: CommandSource): DeviceSetMaximumFloorTemperaturePayload
    deviceSetFrostGuard(deviceId: ID!, frostGuard: Boolean!, commandSource: CommandSource): DeviceSetFrostGuardPayload
    deviceSetNightSwitch(deviceId: ID!, nightSwitch: Boolean!, commandSource: CommandSource): DeviceSetNightSwitchPayload
    deviceSetRegulatorMode(deviceId: ID!, regulatorMode: Boolean!, commandSource: CommandSource): DeviceSetRegulatorModePayload
    deviceSetEvCharging(deviceId: ID!, chargingOn: Boolean!, commandSource: CommandSource): DeviceTriggerCommandPayload
    deviceInvokeCommand(deviceId: ID!, data: DeviceCommandInput!): DeviceInvokeCommandPayload

    commandRevert(commandId: ID!): CommandRevertPayload

    hubSetGatewayConnected(hubId: ID!, gatewayConnected: HubSetGatewayConnectedInput!): HubSetGatewayConnectedPayload
    hubSetNetworkSsid(hubId: ID!, networkSsid: String!): HubSetNetworkSsidPayload
    hubSetNetworkCredentials(hubId: ID!, networkCredentials: String!): HubSetNetworkCredentialsPayload
    invokeHubCommand(hubId: ID!, payload: HubCommandPayloadInput!): HubCommandExecutionResponse
    # internal only
    hubSetArmed(hubId: ID!, isArmed: Boolean!, disarmTimeout: Int): HubSetArmedPayload
    setCollectiveAlarmForHomeHubs(homeId: ID!, active: Boolean!, alarmType: AlarmType!): SetCollectiveAlarmForHomeHubsPayload

    # manufacturing
    hubProvisioning: HubProvisioningPayload!
    hubProvisioningQrGeneration(hubId: ID!): HubProvisioningQrGenerationPayload!
    hubProvisioningRegistryUpdate(hubId: ID!, data: HubProvisioningRegistryUpdateInput!): HubProvisioningRegistryUpdatePayload!
    hubProvisioningAcceptance(hubId: ID!): HubProvisioningAcceptancePayload!
    hubProvisioningDecomission(hubId: ID!): HubProvisioningDecomissionPayload!
    hubProvisioningManufacturingUpdate(hubId: ID!, data: HubProvisioningManufacturingUpdateInput!): HubProvisioningManufacturingUpdatePayload!
    deviceWaterSensorProvisioning(data: DeviceWaterSensorProvisioningInput!): DeviceWaterSensorProvisioningPayload!

    deviceUpdateName(deviceId: ID!, name: String!): DeviceUpdateNamePayload
    deviceToggleFavorite(deviceId: ID!): DeviceToggleFavoritePayload
    homeCreate(data: HomeCreateInput!): HomeCreatePayload
    homeWithoutOwnerCreate(data: HomeWithoutOwnerInput): HomeWithoutOwnerCreatePayload
    homeDelete(homeId: ID!): HomeDeletePayload
    homeUpdate(homeId: ID!, data: HomeUpdateInput!): HomeUpdatePayload
    homeSetInsuranceInfo(homeId: ID!, data: HomeInsuranceInfoInput!): HomeSetInsuranceInfoPayload
    homeMemberAcceptInvitation(homeMemberInvitationId: ID!, token: String!): HomeMemberAcceptInvitationPayload
    homeMemberRejectInvitation(homeMemberInvitationId: ID!, token: String!): HomeMemberRejectInvitationPayload
    homeMemberRevokeInvitation(homeMemberInvitationId: ID!): HomeMemberRevokeInvitationPayload
    homeMemberUpdateInvitation(homeMemberInvitationId: ID!, data: HomeMemberUpdateInvitationInput!): HomeMemberUpdateInvitationPayload
    homeMemberInvite(homeId: ID!, data: HomeMemberInviteInput!, method: HomeMemberInviteMethod!): HomeMemberInvitePayload
    homeMemberInvitationSend(homeMemberInvitationId: ID!, method: HomeMemberInviteMethod!): HomeMemberInvitationSendPayload
    homeMemberUpdate(homeMemberId: ID!, data: HomeMemberUpdateInput!): HomeMemberUpdatePayload
    homeMemberUpdateRole(homeMemberId: ID!, role: HomeMemberRole!): HomeMemberUpdateRolePayload
    homeMemberDelete(homeMemberId: ID!): HomeMemberDeletePayload
    hubUnregister(hubId: ID!): HubUnregisterPayload
    hubRegister(homeId: ID!, hubId: ID!): HubRegisterPayload
    hubRegisterDeviceWithQrCode(qrCode: String!, hubId: ID!, deviceType: DeviceType!, deviceManufacturer: ID!): HubRegisterDeviceWithQrCodePayload
    hubScanDevices(hubId: ID!, deviceType: DeviceType!, deviceManufacturerId: ID!): HubScanDevicesPayload  # @GuidedTour("DeviceRegistationScan", 1)
    hubKeepDevices(hubId: ID!, devices: [String!]!): HubKeepDevicesPayload  # @GuidedTour("DeviceRegistationScan", 5)
    hubUpdateName(hubId: ID!, name: String!): HubUpdateNamePayload
    hubResolveWaterGuardTamperMode(hubId: ID!): HubResolveWaterGuardTamperModePayload
    hubResolveWaterGuardTamperWarningNotification(hubId: ID!): HubResolveWaterGuardTamperWarningNotificationPayload
    userMyAccountUpdate(data: MyAccountUpdateInput!): MyAccountUpdatePayload
    userMyAccountUpdateLocale(language: String!): UserMyAccountUpdateLocalePayload
    userMyAccountVerifyEmail(email: String!): UserMyAccountVerifyEmailPayload   @deprecated(reason: "Use userMyAccountResendPostRegistrationPasswordResetEmail")
    userMyAccountResendPostRegistrationPasswordResetEmail(email: String!): userMyAccountResendPostRegistrationPasswordResetEmailPayload
    userInvite(campaignId: ID!, data: UserInviteInput!): UserInvitePayload
    userAcceptInvitation(invitationId: ID!, token: String!): UserAcceptInvitationPayload
    userAccountSetRole(userId: ID!, role: Role!): UserAccountSetRolePayload
    userDelete(id: ID!): UserDeletePayload

    # internal
    commandUpdateNotification(commandId: ID!, data: CommandUpdateInput!): CommandUpdatePayload
    updateNotificationDeviceGroupCommand(commandId: ID!, commandState: CommandState!): DeviceGroupCommandUpdatedPayload
    updateNotificationCommand(commandId: ID!, commandState: CommandState!): CommandUpdatedPayloadV2
    deviceUpdatedNotification(homeId: ID!, deviceId: ID!): DeviceUpdatedPayload
    hubUpdatedNotification(homeId: ID!, hubId: ID!): HubUpdatedPayload
    hubRegisteredDevicesNotification(commandId: ID!, commandStatus: String, devices: HubRegisteredDevicesInput!): HubRegisteredDevicesPayload
    hubScanFoundDevicesNotification(commandId: ID!, commandStatus: String, foundDevices: HubScanFoundDevicesInput!): HubScanFoundDevicesPayload
    hubKeepDevicesFinishedNotification(commandId: ID!, commandStatus: String, keepDevices: HubKeepDevicesFinishedInput!): HubKeepDevicesFinishedPayload
    userMyAccountVerifyEmailNotification(account: MyAccountInternalUpdateInput!): UserMyAccountVerifyEmailNotificationPayload
    userMyAccountAvatarUpdateNotification(account: MyAccountInternalUpdateInput!): UserMyAccountAvatarUpdateNotificationPayload
    updateNotificationUserSubscription(userId: ID!, data: UserSubscriptionUpdateInput!): UserSubscriptionUpdatedPayload
    homeAvatarUpdateNotification(homeId: ID!, data: HomeAvatarUpdateNotificationInput!): HomeAvatarUpdatedPayload
    alarmUpdatedNotification(homeId: ID!, alarmId: ID, alarm: alarmUpdatedNotificationInput!): AlarmUpdatedPayload
    updateNotificationProject(projectId: ID!): ProjectUpdatedPayload
    # Mutation structure that is used for universal subscription.
    # It will return UpdatedPayload with partyId for every specific party that has access to the resource
    # Every specific notification will have its own input. Example for device updated notification with updated structure:
    # deviceUpdatedNotification(deviceId: ID!, data: TraitsUpdateInput!): UpdatedPayload
    updateNotification: UpdatedPayload
    updateNotificationInvitation(partyId: ID, homeId: ID, action: UpdatedAction!, invitationId: ID!, invitation: HomeMemberInvitationNotificationInput!): UpdatedPayload
    updateNotificationHomeMember(partyId: ID, homeId: ID, action: UpdatedAction!, memberId: ID!, member: HomeMemberNotificationInput): UpdatedPayload
    updateNotificationCloudConnection(partyId: ID, homeId: ID!, action: UpdatedAction!, providerId: ID!): UpdatedPayload
    updateNotificationAlarmStationInfo(partyId: ID, homeId: ID!, action: UpdatedAction!, alarmStationInfo: AlarmStationInfoInput!): UpdatedPayload
    updateNotificationDevice(partyId: ID, homeId: ID!, action: UpdatedAction!, deviceId: ID!): UpdatedPayload
    updateNotificationDeviceGroup(partyId: ID, homeId: ID!, action: UpdatedAction!, deviceGroupId: ID!): UpdatedPayload
    updateNotificationFreezeProtection(partyId: ID, homeId: ID!, action: UpdatedAction!): UpdatedPayload
    updateNotificationRoutine(partyId: ID, homeId: ID!, action: UpdatedAction!, routineId: ID!): UpdatedPayload
    updateNotificationSmartEnergy(partyId: ID, homeId: ID!, action: UpdatedAction!): UpdatedPayload
    updateNotificationCollectiveAlarm(partyId: ID, homeId: ID!, action: UpdatedAction!, alarmType: AlarmType!): UpdatedPayload
    # Mutations for universal user context subscriptions
    updateNotificationDemandResponse(userId: ID!, action: UpdatedAction!): UserUpdatedPayload
    updateNotificationAccount(userId: ID!, action: UpdatedAction!): UserUpdatedPayload

    # to be implemented in the further future
    areaSetActionAccessPolicyForUser(areaId: ID!, userId: ID!, accessInput: ChangeActionAccessesInput!): AreaSetActionAccessPolicyForUserPayload
    deviceSetAccessPolicyForUser(deviceId: ID!, userId: ID!, deviceAccessPolicy: DeviceAccessPolicyInput!): DeviceSetAccessPolicyForUserPayload

    # Installer
    installerCreateProject(data: ProjectCreateInput!): ProjectCreatePayload
    installerUpdateProject(projectId: ID!, data: ProjectUpdateInput!): ProjectUpdatePayload
    installerProjectUpdateStatus(projectId: ID!, status: ProjectStatus!): InstallerProjectUpdateStatusPayload
    claimHome(homeId: ID!): ClaimHomePayload
    installerDeleteProject(projectId: ID!): ProjectDeletePayload
    installerCreateHome(homeId: ID!):  HomeCreatePayload
    installerOrganizationAddInstaller(organizationId: ID!, email: String!): InstallerOrganizationAddInstallerPayload
    installerOrganizationRemoveInstaller(userId: ID!, organizationId: ID!): InstallerOrganizationRemoveInstallerPayload
    installerCreateOrganizationWithOwner(data: InstallerCreateOrganizationWithOwnerInput!): InstallerCreateOrganizationWithOwnerPayload
    installerOrganizationCreateProject(organizationId: ID!, data: ProjectCreateInput!): InstallerOrganizationCreateProjectPayload
    installerOrganizationCreateProjectOnExistingHome(data: OrganizationProjectOnExistingHomeCreateInput!): InstallerOrganizationCreateProjectOnExistingHomePayload
    projectOnExistingHomeCreate(data: ProjectOnExistingHomeCreateInput!): ProjectOnExistingHomeCreatePayload

    # emergency contacts
    homeMemberSetEmergencyNotifications(memberId: ID!, data: HomeMemberSetEmergencyNotificationsInput!): HomeMemberToggleEmergencyNotificationsPayload
    emergencyContactDelete(emergencyContactId: ID!): EmergencyContactDeletePayload
    emergencyContactAdd(homeId: ID!, data: EmergencyContactAddInput!): EmergencyContactAddPayload
    emergencyContactUpdate(emergencyContactId: ID!, data: EmergencyContactUpdateInput!): EmergencyContactUpdatePayload

    # alarm station
    alarmStationEnable(homeId: ID!, overrideName: String): AlarmStationEnablePayload
    alarmStationDisable(homeId: ID!): AlarmStationDisablePayload
    alarmStationAddEmergencyContact(homeId: ID!, data: AlarmStationAddEmergencyContactInput!): AlarmStationAddEmergencyContactPayload
    alarmStationUpdateEmergencyContact(homeId: ID!, id: ID!, data: AlarmStationUpdateEmergencyContactInput!): AlarmStationUpdateEmergencyContactPayload
    alarmStationDeleteEmergencyContact(homeId: ID!, id: ID!): AlarmStationDeleteEmergencyContactPayload

    # subscriptions (odoo)
    updateUserSubscriptions(userId: ID!, data: UpdateUserSubscriptionsInput!): UpdateUserSubscriptionsPayload

    # user preferences
    userUpdatePreferences(data: UserUpdatePreferencesInput!): UserUpdatePreferencesPayload
    userUpdateNotificationPreferences(data: NotificationPreferencesInput!): UserUpdateNotificationPreferencesPayload
    updateUserMarketingPreferences(userId: ID!, data: MarketingPreferencesInput!): UpdateUserMarketingPreferencesPayload

    # device groups
    deviceGroupCreate(homeId: ID!, data: DeviceGroupCreateInput!): DeviceGroupCreatePayload
    deviceGroupUpdate(deviceGroupId: ID!, data: DeviceGroupUpdateInput!): DeviceGroupUpdatePayload
    deviceGroupDelete(deviceGroupId: ID!): DeviceGroupDeletePayload
    deviceGroupSetArmed(deviceGroupId: ID!, isArmed: Boolean!, disarmTimeout: Int): DeviceGroupTriggerCommandPayload
    deviceGroupSetBrightness(deviceGroupId: ID!, brightness: Float!): DeviceGroupTriggerCommandPayload
    deviceGroupSetColor(deviceGroupId: ID!, color: DeviceSetColorInput!): DeviceGroupTriggerCommandPayload
    deviceGroupSetOnOff(deviceGroupId: ID!, isOn: Boolean!): DeviceGroupTriggerCommandPayload
    deviceGroupSetOpenPercent(deviceGroupId: ID!, openPercent: Float!): DeviceGroupTriggerCommandPayload
    deviceGroupSetUnlocked(deviceGroupId: ID!, isUnlocked: Boolean!): DeviceGroupTriggerCommandPayload
    deviceGroupSetChildLock(deviceGroupId: ID!, childLock: Boolean!): DeviceGroupTriggerCommandPayload
    deviceGroupSetTemperature(deviceGroupId: ID!, temperature: Float!): DeviceGroupTriggerCommandPayload
    deviceGroupSetTemperaturePercentage(deviceGroupId: ID!, temperature: Float!): DeviceGroupTriggerCommandPayload
    deviceGroupSetClimateMode(deviceGroupId: ID!, climateMode: ClimateMode!): DeviceGroupTriggerCommandPayload
    deviceGroupSetMaximumFloorTemperature(deviceGroupId: ID!, maximumFloorTemperature: Float!): DeviceGroupTriggerCommandPayload
    deviceGroupSetFrostGuard(deviceGroupId: ID!, frostGuard: Boolean!): DeviceGroupTriggerCommandPayload
    deviceGroupSetNightSwitch(deviceGroupId: ID!, nightSwitch: Boolean!): DeviceGroupTriggerCommandPayload
    deviceGroupSetRegulatorMode(deviceGroupId: ID!, regulatorMode: Boolean!): DeviceGroupTriggerCommandPayload

    # favorites
    favoritesAdd(subjectId: ID!, subjectType: FavoriteSupportedType!): FavoritesAddPayload
    favoritesRemove(subjectId: ID!, subjectType: FavoriteSupportedType!): FavoritesRemovePayload

    # freeze mode
    freezeProtectionConfigure(homeId: ID!, data: FreezeProtectionConfigureInput!): FreezeProtectionConfigurePayload

    # routines
    # routine when created by the system requires different data, that could not been authorized with available code,
    # when refactored then Internal endpoint might not be needed anymore.
    routineCreate(homeId: ID!, data: RoutineCreateInput!): RoutineCreatePayload
    routineCreateInternal(homeId: ID!, data: RoutineCreateInternalInput!): RoutineCreatePayload
    routineUpdateDescription(routineId: ID!, data: RoutineUpdateDescriptionInput!): RoutineUpdateDescriptionPayload
    routineActivate(routineId: ID!): RoutineActivatePayload
    routineDeactivate(routineId: ID!): RoutineDeactivatePayload
    routineDelete(routineId: ID!): RoutineDeletePayload
    routineUpdate(routineId: ID!, data: RoutineUpdateInput!): RoutineUpdatePayload

    # Establishes an AWS pinpoint endpoint (residing in the `address` field in `data` input)
    # for the calling user. Additionally a push notification channel needs to be provided
    # `channel` field in the input. Upon setting a push notification endpoint with this
    # mutation, a user will receive push notifications on given address through given channel.
    pushNotificationEndpointSet(data: PushNotificationEndpointInput!): PushNotificationEndpointSetPayload

    notificationInboxMarkAsRead(notificationIds: [ID!]!): NotificationInboxMarkAsReadPayload

    # demand response
    demandResponseEnroll: DemandResponseEnrollPayload
    demandResponseUnenroll: DemandResponseUnenrollPayload

    # smart energy
    smartEnergyEnable(homeId: ID!, hourlyLimitWatts: Int!): SmartEnergyEnablePayload
    smartEnergyDisable(homeId: ID!): SmartEnergyDisablePayload
    smartEnergySetHourlyLimit(homeId: ID!, hourlyLimitWatts: Int!): SmartEnergySetHourlyLimitPayload
    smartEnergyEnableDevice(homeId: ID!, deviceId: ID!): SmartEnergyEnableDevicePayload
    smartEnergyDisableDevice(homeId: ID!, deviceId: ID!): SmartEnergyDisableDevicePayload

    # housing association
    housingAssociationCollectiveAlarmCreateZone(housingAssociationId: ID!): HousingAssociationCollectiveAlarmCreateZonePayload
    housingAssociationCollectiveAlarmDeleteZone(zoneId: ID!): HousingAssociationCollectiveAlarmDeleteZonePayload
    housingAssociationCollectiveAlarmConfigureZone(zoneId: ID!, data: CollectiveAlarmZoneConfigurationInput!): HousingAssociationCollectiveAlarmConfigureZonePayload
    housingAssociationCollectiveAlarmZoneAddFacility(zoneId: ID!, data: ZoneAddFacilityInput!): HousingAssociationCollectiveAlarmZoneAddFacilityPayload
    housingAssociationCollectiveAlarmZoneRemoveFacility(zoneId: ID!, facilityId: ID!): HousingAssociationCollectiveAlarmZoneRemoveFacilityPayload

    ## temporary, until we fully support adding homes to HA, accepts homeId's - units or common areas
    housingAssociationBuildingAddFacilityTemp(housingAssociationId: ID!, buildingId: ID!, homeId: ID!, isCommonArea: Boolean!): HousingAssociationBuildingAddFacilityTempPayload
    housingAssociationBuildingRemoveFacilityTemp(buildingId: ID!, homeId: ID!): HousingAssociationBuildingRemoveFacilityTempPayload

    # collective alarms
    ## internal
    collectiveAlarmCreate(collectiveAlarmId: ID!): CollectiveAlarmCreatePayload
    collectiveAlarmDelete(collectiveAlarmId: ID!): CollectiveAlarmDeletePayload
    collectiveAlarmSetTenants(collectiveAlarmId: ID!, tenants: [ID!]!): CollectiveAlarmSetTenantsPayload

    # geofence safeboat
    activateGeofence(homeId: ID!, hubId: ID!, activateGeofenceInput: ActivateGeofenceInput!): GeofenceActivatePayload
    deactivateGeofence(homeId: ID!, deactivateGeofenceInput: DeactivateGeofenceInput!): GeofenceDeactivatePayload
    setMOBCountdown(homeId: ID!, setMOBCountdownInput: SetMOBCountdownInput!): GeofenceSetMOBCountdownPayload
    sendMOBEmergencyMessage(homeId: ID!): GeofenceSendMOBEmergencyMessagePayload
    cancelMOBEmergency(homeId: ID!): GeofenceCancelMOBEmergencyPayload
}


type Subscription {
    commandUpdated(homeId: ID, commandId: ID): CommandUpdatePayload @aws_subscribe(mutations: ["commandUpdateNotification"])
    deviceGroupCommandUpdated(commandId: ID!): DeviceGroupCommandUpdatedPayload @aws_subscribe(
        mutations: ["updateNotificationDeviceGroupCommand"]
    )
    commandUpdatedV2(commandId: ID!): CommandUpdatedPayloadV2 @aws_subscribe(mutations: ["updateNotificationCommand"])
    deviceUpdated(homeId: ID!): DeviceUpdatedPayload @aws_subscribe(mutations: ["deviceUpdatedNotification"])
    hubUpdated(homeId: ID!): HubUpdatedPayload @aws_subscribe(mutations: ["hubUpdatedNotification"])
    hubRegisteredDevices(commandId: ID!): HubRegisteredDevicesPayload @aws_subscribe(mutations: ["hubRegisteredDevicesNotification"])
    hubScanFoundDevices(commandId: ID!): HubScanFoundDevicesPayload @aws_subscribe(mutations: ["hubScanFoundDevicesNotification"])
    hubKeepDevicesFinished(commandId: ID!): HubKeepDevicesFinishedPayload @aws_subscribe(mutations: ["hubKeepDevicesFinishedNotification"])
    userMyAccountEmailVerified(email: String!): UserMyAccountVerifyEmailNotificationPayload @aws_subscribe(mutations: ["userMyAccountVerifyEmailNotification"])
    userMyAccountAvatarUploaded(email: String!): UserMyAccountAvatarUpdateNotificationPayload @aws_subscribe(mutations: ["userMyAccountAvatarUpdateNotification"])
    userSubscriptionUpdated(userId: ID!): UserSubscriptionUpdatedPayload @aws_subscribe(mutations: ["updateNotificationUserSubscription"])
    alarmUpdated(homeId: ID!, alarmId: ID): AlarmUpdatedPayload @aws_subscribe(mutations: ["alarmUpdatedNotification"])
    projectUpdated(projectId: ID!): ProjectUpdatedPayload @aws_subscribe(mutations: ["updateNotificationProject"])
    homeAvatarUpdated(homeId: ID!): HomeAvatarUpdatedPayload @aws_subscribe(mutations: ["homeAvatarUpdateNotification"])
    # Subscription structure that is used for universal subscription. PartyId is used for filtering permitted clients
    # and homeId can be used for filtering for specific home if client wants to
    # partyId temporarily made non-required
    homeUpdated(partyId: ID, homeId: ID): UpdatedPayload @aws_subscribe(
        mutations: [
            "updateNotification",
            "updateNotificationInvitation",
            "updateNotificationHomeMember",
            "updateNotificationCloudConnection",
            "updateNotificationAlarmStationInfo",
            "updateNotificationDevice",
            "updateNotificationDeviceGroup",
            "updateNotificationFreezeProtection",
            "updateNotificationRoutine",
            "updateNotificationSmartEnergy",
            "updateNotificationCollectiveAlarm",
        ]
    )
    userUpdated(userId: ID!): UserUpdatedPayload @aws_subscribe(
        mutations: [
            "updateNotificationDemandResponse",
            "updateNotificationAccount",
        ]
    )
}



input HubProvisioningRegistryUpdateInput {
    homekitSetupCode: String!
    homekitSetupPayload: String!
    dppPayload: String!
    abraPayload: String!
    macAddress: String!
    zigbeeTestResult: String!
    wimeaTestResult: String!
    wifiTestResult: String!
    lteTestResult: String!
    ethernetTestResult: String!
    sanityTestResult: String!
    dynamicLink: String!
    batchNumber: String
    productId: String
    purchaseOrder: String
    productType: HubProductType
    imei: String
    imsi: String
}

input HubProvisioningManufacturingUpdateInput {
    serialNumber: String
}

input DeviceWaterSensorProvisioningInput {
    serialNumber: String!
    macAddress: String!
}

input HomeInfoInput {
    nickname: String!
    avatarUrl: String
    size: Float
    ageOfBuilding: Int @deprecated(reason: "same as buildingYear")
    numberOfFloors: Int
    numberOfAdults: Int
    numberOfChildren: Int
    homeType: HomeType
    dwellingUnit: HomeDwellingUnit
    heatingType: HeatingType
    cooling: CoolingType
    ventilation: Boolean
    constructionType: ConstructionType
    buildingYear: Int
}

input GeoLocationInput {
    latitude: Float!
    longitude: Float!
}

input HomeLocationInput {
    country: String!
    city: String!
    street: String!
    postalCode: String!
    streetNumber: String
    unitNumber: String
    geoLocation: GeoLocationInput
    apartmentNumber: String
    associationPk: ID
}

input HubCommandPayloadInput {
    topic: String!
    commandBody: String!
}

input HomeCreateInput {
    locationInfo: HomeLocationInput
    homeInfo: HomeInfoInput!
}

input HomeWithoutOwnerInput{
    homeId: ID!
    locationInfo: HomeLocationInput
    homeInfo: HomeInfoInput!
}

input HomeUpdateInput {
    locationInfo: HomeLocationInput
    homeInfo: HomeInfoInput
}

input HomeMemberInviteInput {
    firstName: String!
    lastName: String!
    email: String!
    phoneNumber: PhoneNumberInput
    role: HomeMemberRole!
}

input HomeMemberUpdateInvitationInput {
    firstName: String
    lastName: String
    phoneNumber: PhoneNumberInput
    role: HomeMemberRole
}

input HomeMemberUpdateInput {
    firstName: String
    lastName: String
    phoneNumber: PhoneNumberInput
}

input AreaCreateInput {
    areaName: String!
    areaType: AreaType!
    size: Float
    floor: Int
    children: Boolean
}

input AreaUpdateInput {
    areaName: String
    areaType: AreaType
    size: Float
    floor: Int
    children: Boolean
}

input ChangeActionAccessesInput {
    actionType: HomeProfileActionType!

    create: Boolean!
    update: Boolean!
    delete: Boolean!
    read: Boolean!
}

input DeviceAccessPolicyInput {
    read: Boolean!
    write: Boolean!
    delete: Boolean!

    expiresAt: String
}

input PhoneNumberInput {
    countryCode: String!
    nationalNumber: String!
}

input MyAccountUpdateInput {
    firstName: String
    lastName: String
    phoneNumber: PhoneNumberInput
}

input MyAccountInternalUpdateInput {
    email: String!
    emailVerified: Boolean
    url: String
    urlSmall: String
    urlMedium: String
    urlLarge: String
}

input UserSubscriptionUpdateInput {
    subscriptionType: SubscriptionType!
    tokensTotal: Int!
    tokensAvailable: Int!
}

input alarmUpdatedNotificationInput {
    id: ID!
    state: AlarmState!
    stateId: ID!
    triggeredAt: String
    snoozeExpiresAt: String
    isArmed: Boolean
    typename__: String!  # is replaced with __typename in VTL
    areaIds: [ID!]!
}

input HomeMemberNotificationInput {
    id: ID!
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumberInput
    userId: String!
    typename__: String!  # is replaced with __typename in VTL
}

input AlarmStationInfoContactsInput {
    id: ID!
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumberInput!
}

input AlarmStationInfoInput {
    homeId: ID!
    status: String!
    contacts: [AlarmStationInfoContactsInput!]!
}

input HomeMemberInvitationNotificationInput {
    id: ID!
    firstName: String!
    lastName: String!
    email: String!
    phoneNumber: PhoneNumberInput
    role: HomeMemberRole!
    status: HomeMemberInvitationStatus!
    expiresAt: String!
}

input HomeAvatarUpdateNotificationInput {
    url: String!
    urlSmall: String!
    urlMedium: String!
    urlLarge: String!
}

input CommandUpdateInput {
    commandState: CommandState!
}

input TraitsUpdateInput {
    jsonData: String!
}

input HubScanDevicesErrorInput {
    message: String!
}

input HubDeviceInput {
    hubDeviceId: ID!
    hubDeviceManufacturerName: String!
    hubDeviceModel: String!
    hubDeviceMacAddress: String!
}

input HubScanFoundDevicesInput {
    devices: [HubDeviceInput!]!
    errors: [HubScanDevicesErrorInput!]!
}

input HubKeepDevicesFinishedErrorInput {
    message: String!
}

input HubKeepDevicesFinishedInput {
    errors: [HubKeepDevicesFinishedErrorInput!]!
}

input HubRegisteredDevicesErrorInput {
    message: String!
}

input HubRegisteredDevicesInput {
    devices: [HubDeviceInput!]!
    errors: [HubRegisteredDevicesErrorInput!]!
}

input DeviceSetColorInput {
    hue: Float
    saturation: Float
}

enum DeviceCommand {
    EV_CHARGE
    EV_CHARGING_SPEED
    TURN_ON
}

input DeviceCommandEvChargingSpeedInput {
    amperage: Int!
}

input DeviceCommandEvChargeInput {
    chargingOn: Boolean!
}

input DeviceCommandTurnOnInput {
    isOn: Boolean!
}

input DeviceCommandInput {
    commandId: ID
    commandType: DeviceCommand!
    source: CommandSource
    triggerMeta: CommandTriggerMeta
    evChargingSpeed: DeviceCommandEvChargingSpeedInput
    evCharge: DeviceCommandEvChargeInput
    turnOn: DeviceCommandTurnOnInput
}

input HubSetGatewayConnectedInput {
    ethernetConnected: Boolean
    wifiConnected: Boolean
    cellularConnected: Boolean
}

input UserInviteInput {
	email: String!
	firstName: String!
	lastName: String!
	phoneNumber: PhoneNumberInput!
    address: String!
    city: String!
    region: String
    postalCode: String!
}

input AlarmPreferencesInput {
    securityShowArmConfirmationModal: Boolean
}

input GeneralPreferencesInput {
    betaVersion: Boolean
    experimentalVersion: Boolean
}

input NotificationPreferencesInput {
    notificationsEnabled: Boolean
}

input MarketingPreferencesInput {
    marketingConsent: Boolean
    registrationSource: RegistrationSource
}

input UserUpdatePreferencesInput {
    alarmPreferences: AlarmPreferencesInput
    generalPreferences: GeneralPreferencesInput
}

# Stats
input TimeSeriesSelectInput {
    tag: String!
    category: TimeSeriesCategory!
    homeId: ID
    areaId: ID
    deviceId: ID
    aggregateSum: Boolean
}

enum TimeSeriesCategory {
    ENERGY_CONSUMPTION
    ENERGY_CONSUMPTION_COST
    ENERGY_CONSUMPTION_HEATING
    ENERGY_CONSUMPTION_COST_HEATING
    ENERGY_CONSUMPTION_COOLING
    ENERGY_CONSUMPTION_COST_COOLING
    ENERGY_CONSUMPTION_BEHAVIOUR
    ENERGY_CONSUMPTION_COST_BEHAVIOUR
    ENERGY_CONSUMPTION_ALWAYS_ON
    ENERGY_CONSUMPTION_COST_ALWAYS_ON
    ENERGY_CONSUMPTION_PREDICTED
    ENERGY_CONSUMPTION_COST_PREDICTED
    ENERGY_SPOT_PRICE
    TEMPERATURE_INSIDE
    TEMPERATURE_OUTSIDE
    AGGREGATED_ENERGY_CONSUMPTION_COST
    AGGREGATED_ENERGY_CONSUMPTION
    HUMIDITY
}

input StatsScopeInput {
    rangeStart: String!  # in Zulu time (UTC)
    rangeEnd: String!  # in Zulu time (UTC)
    granularity: Granularity!
}

enum Granularity {
    HOURLY
    DAILY
    MONTHLY
}

enum EnergyUnit {
    KILOWATT_HOUR
}

enum TimeSeriesUnit {
    CELSIUS
    KILOWATT_HOUR
    NORWEGIAN_KRONE
    NORWEGIAN_KRONE_PER_KILOWATT_HOUR
    PERCENTAGE
}

type DemandResponse   {
    eligible: Boolean!
    enrolled: Boolean!
}

type SmartEnergyDevice   {
    enabled: Boolean!
    deviceId: ID!
}

type SmartEnergyConfiguration   {
    hourlyLimitWatts: Int!
}


type SmartEnergy   {
    enabled: Boolean!
    configuration: SmartEnergyConfiguration
    devices: [SmartEnergyDevice!]!
}

type TimeSeriesRef {
    timeSeriesId: ID!
    category: TimeSeriesCategory!
    homeId: ID
    areaId: ID
    deviceId: ID
}

type TimeSeriesValue {
    tag: String!
    value: Float!
}

type TimeSeriesSamples {
    timestamp: Int!
    values: [TimeSeriesValue!]!
}

type TimeSeriesMetadata {
    tag: String!
    ref: TimeSeriesRef!
    unit: TimeSeriesUnit!
}

type TimeSeriesAggregate {
    tag: String!
    sum: Float!
}

type TimeSeriesResult {
    metadata: [TimeSeriesMetadata!]!
    values: [TimeSeriesSamples!]!
    aggregates: [TimeSeriesAggregate!]!
}

type TimeSeriesPayload {
    result: TimeSeriesResult
    errors: [TimeSeriesError!]!
}

# Hub Provisioning
type HubProvisioningRegistryUpdatePayload  {
    errors: [HubProvisioningRegistryUpdateError!]!
}

type HubProvisioningManufacturingUpdatePayload  {
    errors: [HubProvisioningManufacturingUpdateError!]!
}

type HubProvisioningQrGenerationPayload  {
    qrCode: String!
    errors: [HubProvisioningQrGenerationError!]!
}

type HubProvisioningPayload  {
    hubId: String!
    certificatePem: String!
    privateKey: String!
    errors: [HubProvisioningError!]!
}

type HubProvisioningAcceptancePayload  {
    errors: [HubProvisioningAcceptanceError!]!
}

type HubProvisioningDecomissionPayload  {
    errors: [HubProvisioningDecomissionError!]!
}

type DeviceWaterSensorProvisioningPayload  {
    deviceId: String!
}

# Home
type HomeCreatePayload {
    home: Home
    errors: [HomeCreateError!]!
}

type HomeWithoutOwnerCreatePayload  {
    home: Home
    errors: [HomeCreateError!]!
}

type HomeUpdatePayload {
    home: Home
    errors: [HomeUpdateError!]!
}

type HomeDeletePayload   {
    homeId: ID
    errors: [HomeDeleteError!]!
}

type AreaCreatePayload {
    area: Area
    errors: [AreaCreateError!]!
}

type AreaUpdatePayload {
    area: Area
    errors: [AreaUpdateError!]!
}

type AreaDeletePayload {
    areaId: ID
    errors: [AreaDeleteError!]!
}

type AreaAddDevicePayload {
    area: Area
    errors: [AreaAddDeviceError!]!
}

type AreaRemoveDevicePayload {
    area: Area
    errors: [AreaRemoveDeviceError!]!
}

type AreaAddHubPayload {
    area: Area
    errors: [AreaAddHubError!]!
}

type AreaRemoveHubPayload {
    area: Area
    errors: [AreaRemoveHubError!]!
}

type HubRegisterPayload {
    hub: Hub
    errors: [HubRegisterError!]!
}

type HubRegisteredDevicesPayload   {
    commandId: ID!
    deviceIds: [ID!]!
    errors: [HubRegistrationDevicesError!]!
}

type HubScanDevicesPayload {
    commandId: String
    timeoutSeconds: Int
    errors: [HubScanDevicesError!]!
}

type HubScanFoundDevice   {
    hubDeviceId: ID!
    deviceName: String!
    deviceManufacturerName: String!
    deviceImageSmallUrl: String!
    serialNumber: String!
}

type HubCollectiveAlarm  {
    hubId: ID!
    active: Boolean!
}

type HubScanFoundDevicesPayload   {
    commandId: String!
    devices: [HubScanFoundDevice!]!
    errors: [HubScanFoundDevicesError!]!
}

type HubKeepDevicesPayload {
    commandId: String
    timeoutSeconds: Int
    errors: [HubKeepDevicesError!]!
}

type HubKeepDevicesFinishedPayload   {
    commandId: String!
    deviceIds: [ID!]!
    errors: [HubKeepDevicesFinishedError!]!
}

type HubUnregisterPayload   {
    hub: Hub
    errors: [HubUnregisterError!]!
}

type HubUpdateNamePayload {
    hub: Hub
    errors: [HubUpdateNameError!]!
}

type HubResolveWaterGuardTamperModePayload   {
    hub: Hub
    errors: [HubResolveWaterGuardTamperModeError!]!
}

type HubResolveWaterGuardTamperWarningNotificationPayload {
    hub: Hub
    errors: [HubResolveWaterGuardTamperWarningNotificationError!]!
}

type AreaSetActionAccessPolicyForUserPayload {
    actionAccesses: [HomeProfileActionAccess!]
    errors: [PayloadError!]!
}

type HomeMemberAcceptInvitationPayload {
    homeId: ID
    errors: [HomeMemberAcceptInvitationError!]!
}

type HomeMemberRejectInvitationPayload {
    errors: [HomeMemberRejectInvitationError!]!
}

type HomeMemberRevokeInvitationPayload {
    homeMemberInvitation: HomeMemberInvitation
    errors: [HomeMemberRevokeInvitationError!]!
}

type HomeMemberInvitePayload   {
    homeMemberInvitation: HomeMemberInvitation
    dynamicLink: String
    errors: [HomeMemberInvitationError!]!
}

type HomeMemberUpdateInvitationPayload {
    homeMemberInvitation: HomeMemberInvitation
    errors: [HomeMemberUpdateInvitationError!]!
}

type HomeMemberInvitationSendPayload {
    homeMemberInvitation: HomeMemberInvitation
    dynamicLink: String
    errors: [HomeMemberInvitationSendError!]!
}

type HomeMemberUpdatePayload {
    homeMember: HomeMember
    errors: [HomeMemberUpdateError!]!
}

type HomeMemberUpdateRolePayload {
    homeMember: HomeMember
    errors: [HomeMemberUpdateRoleError!]!
}

type HomeMemberDeletePayload {
    homeMemberId: ID
    errors: [HomeMemberDeleteError!]!
}

type UserDeletePayload {
    id: ID
    errors: [UserDeleteError!]!
}
type DeviceSetAccessPolicyForUserPayload {
    accessPolicy: DeviceAccessPolicy
    errors: [DeviceSetAccessPolicyForUserError!]!
}

type MyAccountUpdatePayload {
    user: Account
    errors: [UserMyAccountUpdateError!]!
}

type UserMyAccountUpdateLocalePayload {
    errors: [UserMyAccountUpdateLocaleError!]!
}

type HubIdentifyPayload   {
    hubInfo: HubInfo
    errors: [HubIdentifyError!]!
}

type HubGetDppPayload {
    dppPayload: String
    errors: [HubGetDppError!]!
}

type DeviceIdentifyPayload {
    deviceInfo: DeviceInfo
    errors: [DeviceIdentifyError!]!
}

type CommandUpdatePayload   {
    homeId: ID!
    commandId: ID!
    command: Command!
}

type DeviceGroupCommandUpdatedPayload   {
    commandId: ID!
    commandState: CommandState!
}

type CommandUpdatedPayloadV2   {
    commandId: ID!
    commandState: CommandState!
}

type AlarmUpdatedPayload   {
    homeId: ID!
    alarmId: ID!
    alarm: Alarm!
}

type ProjectUpdatedPayload   {
    projectId: ID!
    project: Project
}

type AlarmResolvePayload {
    alarmId: ID!
    alarm: Alarm
    errors: [AlarmResolveError!]!
}

type AlarmSetArmPayload {
    alarmId: ID
    errors: [AlarmSetArmError!]!
}

type AlarmAcknowledgePayload {
    alarmId: ID!
    errors: [AlarmAcknowledgeError!]!
}

type AlarmAlertEmergencyContactsNotificationRequestPayload {
    alarmId: ID
    errors: [AlarmAlertEmergencyContactsNotificationRequestError!]!
}

type AlarmAlertEmergencyContactsNotificationDismissPayload {
    alarmId: ID
    errors: [AlarmAlertEmergencyContactsNotificationDismissError!]!
}

type AlarmImOkEmergencyContactsNotificationRequestPayload {
    alarmId: ID
    errors: [AlarmImOkEmergencyContactsNotificationRequestError!]!
}

type AlarmImOkEmergencyContactsNotificationDismissPayload {
    alarmId: ID
    errors: [AlarmImOkEmergencyContactsNotificationDismissError!]!
}

type HubUpdatedPayload   {
    homeId: ID!
    hubId: ID!
    hub: Hub!
}

type HubRegisterDeviceWithQrCodePayload {
    commandId: ID
    timeoutSeconds: Int
    errors: [HubRegisterDeviceWithQrError!]!
}

type DeviceRegisterByQrCodePayload {
    deviceId: ID
    errors: [DeviceRegisterByQrCodeError!]!
}

type DeviceUnregisterPayload   {
    device: Device
    command: Command
    errors: [DeviceUnregisterError!]!
}

type DeviceUnregisterV2Payload   {
    commandId: ID
    errors: [DeviceUnregisterError!]!
}

type DeviceSetRelayDeviceTypePayload {
    errors: [DeviceSetRelayDeviceTypeError!]!
}

type DeviceSetIoModuleConfigurationPayload {
    errors: [DeviceSetIoModuleConfigurationError!]!
}

type DeviceUpdateNamePayload {
    device: Device
    errors: [DeviceUpdateNameError!]!
}

type DeviceToggleFavoritePayload {
    deviceId: ID
    device: Device
    errors: [DeviceToggleFavoriteError!]!
}

type DeviceSetArmedPayload   {
    device: Device
    command: Command
    errors: [DeviceSetArmedError!]!
}

type HubSetArmedPayload  {
    hub: Hub
    command: Command
    errors: [HubSetArmedError!]!
}

type SetCollectiveAlarmForHomeHubsPayload  {
    errors: [SetCollectiveAlarmForHomeHubsError!]!
}

type DeviceSetBrightnessPayload   {
    device: Device
    command: Command
    errors: [DeviceSetBrightnessError!]!
}

type DeviceSetColorPayload   {
    device: Device
    command: Command
    errors: [DeviceSetColorError!]!
}

type DeviceSetOnOffPayload    {
    device: Device
    command: Command
    errors: [DeviceSetOnOffError!]!
}

type DeviceSetOpenPercentPayload   {
    device: Device
    command: Command
    errors: [DeviceSetOpenPercentError!]!
}

type DeviceSetUnlockedPayload   {
    device: Device
    command: Command
    errors: [DeviceSetUnlockedError!]!
}

type DeviceSetTemperatureSetpointPayload   {
    device: Device
    command: Command
    errors: [DeviceSetTemperatureSetpointError!]!
}

type DeviceSetTemperatureSetpointPercentagePayload   {
    device: Device
    command: Command
    errors: [DeviceSetTemperatureSetpointPercentageError!]!
}

type DeviceSetTemperaturePayload   {
    device: Device
    command: Command
    errors: [DeviceSetTemperatureError!]!
}

type DeviceSetTemperaturePercentagePayload   {
    device: Device
    command: Command
    errors: [DeviceSetTemperaturePercentageError!]!
}

type DeviceSetClimateModePayload   {
    device: Device
    command: Command
    errors: [DeviceSetClimateModeError!]!
}

type DeviceSetMaximumFloorTemperaturePayload   {
    device: Device
    command: Command
    errors: [DeviceSetMaximumFloorTemperatureError!]!
}

type DeviceSetFrostGuardPayload   {
    device: Device
    command: Command
    errors: [DeviceSetFrostGuardError!]!
}

type DeviceSetChildLockPayload   {
    device: Device
    command: Command
    errors: [DeviceSetChildLockError!]!
}

type DeviceSetNightSwitchPayload   {
    device: Device
    command: Command
    errors: [DeviceSetNightSwitchError!]!
}

type DeviceSetRegulatorModePayload   {
    device: Device
    command: Command
    errors: [DeviceSetRegulatorModeError!]!
}

type DeviceTriggerCommandPayload   {
    commandId: ID
    errors: [DeviceTriggerCommandError]!
}

type DeviceInvokeCommandPayload   {
    commandId: ID
    errors: [DeviceInvokeCommandError]!
}

type CommandRevertPayload  {
    errors: [CommandRevertError!]!
}

type HubSetGatewayConnectedPayload {
    hub: Hub
    command: Command
    errors: [HubSetGatewayConnectedError!]!
}

type HubSetNetworkSsidPayload {
    hub: Hub
    command: Command
    errors: [HubSetNetworkSsidError!]!
}

type HubSetNetworkCredentialsPayload {
    hub: Hub
    command: Command
    errors: [HubSetNetworkCredentialsError!]!
}

type AlarmCollection   {
    alarms: [Alarm!]!
}

type Image   {
    url: String!
    urlSmall: String!
    urlMedium: String!
    urlLarge: String!
}

type CloudConnectionCollection   {
    cloudConnections: [CloudConnection!]!
}

type CloudConnectionTemplate   {
    providerName: String!
    providerDescription: String!
    image: Image!
}

interface CloudConnectionInterface {
    providerId: ID!
    status: CloudConnectionStatus!
    connectionError: String
    template(language: String): CloudConnectionTemplate!
}

enum CloudConnectionStatus   {
    CONNECTED
    CONFIGURATION_PENDING
    CONNECTION_ERROR
    DISCONNECTED
    NOT_CONFIGURED
}

type ElhubCloudConnection implements CloudConnectionInterface   {
    providerId: ID!
    status: CloudConnectionStatus!
    connectedAt: String
    connectionError: String
    template(language: String): CloudConnectionTemplate!

    energyMeterIds: [String!]!
}

type NordPoolCloudConnection implements CloudConnectionInterface   {
    providerId: ID!
    status: CloudConnectionStatus!
    connectionError: String
    template(language: String): CloudConnectionTemplate!

    region: String!
    priceMap: Image!
}

union CloudConnection = ElhubCloudConnection | NordPoolCloudConnection

type CloudConnectionDisconnectPayload   {
    errors: [ElhubDisconnectError!]!
}

type ElhubConnectPayload   {
    errors: [ElhubConnectError!]!
}

type SmartChargeUserSyncPayload {
    payload: String
}

type HomeMemberCollection   {
    homeMembers: [HomeMember!]!
}

type HomeMemberInvitationCollection {
    invitations: [HomeMemberInvitation!]!
}

type UserMyAccountVerifyEmailPayload   {
    errors: [UserMyAccountVerifyEmailError!]!
}

type userMyAccountResendPostRegistrationPasswordResetEmailPayload   {
    errors: [userMyAccountResendPostRegistrationPasswordResetEmailError!]!
}

type UserMyAccountVerifyEmailNotificationPayload   {
    email: String!
    account: Account!
}

type UserMyAccountAvatarUpdateNotificationPayload   {
    email: String!
    account: Account!
}

type UserSubscriptionUpdatedPayload   {
    userId: ID!
    subscriptionType: SubscriptionType!
    tokensTotal: Int!
    tokensAvailable: Int!
}

type UserInvitePayload   {
    invitationId: ID
    errors: [UserInviteError!]
}

type UserAcceptInvitationPayload   {
    errors: [UserAcceptInvitationError!]
}

type UserAccountSetRolePayload  {
    errors: [UserAccountSetRoleError!]!
}

type UserUpdatePreferencesPayload {
    errors: [UserUpdatePreferencesError!]
}

type UserUpdateNotificationPreferencesPayload {
    errors: [UserUpdateNotificationPreferencesError!]
}

type UpdateUserMarketingPreferencesPayload  {
    errors: [UpdateUserMarketingPreferencesError!]
}

type HomeAvatarUpdatedPayload   {
    homeId: ID!
    avatar: Avatar!
}

type Organization {
    id: ID!
    name: String!
    address: String!
    email: String!
    phoneNumbers: [PhoneNumber]!
}

enum InstallerOrganizationRole {
    INSTALLER
    OWNER
}

type InstallerOrganizationMember {
    id: ID!
    account: Account!
    role: InstallerOrganizationRole!
}

type InstallerOrganization {
    id: ID!
    name: String!
    projects: InstallerProjectCollection!
    members: [InstallerOrganizationMember!]!
}

type PhoneNumber   {
    countryCode: String!
    nationalNumber: String!
}

type HomeMemberAccount   {
    id: ID!
    email: String!
    avatar: Avatar
}

interface HomeMemberInterface {
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumber
    account: HomeMemberAccount!
    isEmergencyContact: Boolean
    isAlarmStationContact: Boolean
}

type HomeOwner implements HomeMemberInterface   {
    id: ID!
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumber
    account: HomeMemberAccount!
    isEmergencyContact: Boolean
    isAlarmStationContact: Boolean
}

type HomeAdministrator implements HomeMemberInterface   {
    id: ID!
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumber
    account: HomeMemberAccount!
    isEmergencyContact: Boolean
    isAlarmStationContact: Boolean
}

type HomeUser implements HomeMemberInterface   {
    id: ID!
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumber
    account: HomeMemberAccount!
    isEmergencyContact: Boolean
    isAlarmStationContact: Boolean
}

type HomeChild implements HomeMemberInterface   {
    id: ID!
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumber
    account: HomeMemberAccount!
    isEmergencyContact: Boolean
    isAlarmStationContact: Boolean
}

type HomeGuest implements HomeMemberInterface   {
    id: ID!
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumber
    account: HomeMemberAccount!
    isEmergencyContact: Boolean
    isAlarmStationContact: Boolean
}

union HomeMember = HomeOwner | HomeAdministrator | HomeUser | HomeChild | HomeGuest

type HomeMemberInvitation implements Node   {
    id: ID!
    firstName: String!
    lastName: String!
    email: String!
    phoneNumber: PhoneNumber
    role: HomeMemberRole!
    status: HomeMemberInvitationStatus!
    expiresAt: String!
}


type InvitedUserHome implements Node   {
    id: ID!
    name: String
    type: HomeType
    locationInfo: HomeLocationInfo
}


type InvitingUser {
    firstName: String!
    lastName: String!
}

type InvitedUserHomeMemberInvitation implements Node {
    id: ID!
    createdAt: String!
    home: InvitedUserHome!
    invitingUser: InvitingUser!
    role: HomeMemberRole!
    expiresAt: String!
}

type Avatar   {
    url: String!
    urlSmall: String!
    urlMedium: String!
    urlLarge: String!
    uploadUrl: String
}

type ImageUrl   {
    original: String!
    small: String
    medium: String
    large: String
}

type ImageInfo   {
    url: ImageUrl
    uploadUrl: String
}

enum Role {
    INSTALLER
}

enum RegistrationSource {
    ABRA
    SJOLIV
    UNKNOWN
}

type Account implements Node   {
    id: ID!
    email: String!
    emailVerified: Boolean!
    phoneNumber: PhoneNumber
    firstName: String
    lastName: String
    avatar: Avatar  @deprecated(reason: "use avatarV2")
    avatarV2(uploadFile: String): ImageInfo
    roles: [Role!]!
}

type AlarmPreferences {
    securityShowArmConfirmationModal: Boolean!
}

type NotificationPreferences {
    notificationsEnabled: Boolean!
}

type GeneralPreferences {
    betaVersion: Boolean!
    experimentalVersion: Boolean!
}

type AccountPreferences {
    alarmPreferences: AlarmPreferences!
    notificationPreferences: NotificationPreferences!
    generalPreferences: GeneralPreferences!
}

type HomeProfileActionAccess   {
    actionType: HomeProfileActionType!

    create: Boolean!
    update: Boolean!
    delete: Boolean!
    read: Boolean!
}

type HomeInfo   {
    nickname: String!
    avatarUrl: String
    size: Float
    ageOfBuilding: Int @deprecated(reason: "same as buildingYear")
    numberOfFloors: Int
    numberOfAdults: Int
    numberOfChildren: Int
    homeType: HomeType
    dwellingUnit: HomeDwellingUnit
    heatingType: HeatingType
    cooling: CoolingType
    ventilation: Boolean
    propertyManagerName: String
    constructionType: ConstructionType
    buildingYear: Int
}

type GeoLocation   {
    latitude: Float!
    longitude: Float!
}

type HomeLocationInfo   {
    country: String!
    city: String!
    postalCode: String!
    street: String!
    streetNumber: String
    unitNumber: String
    geoLocation: GeoLocation
    apartmentNumber: String
    associationId: ID
}


input HomeInsuranceInfoInput {
    insuranceCompanyId: ID!
}

type HomeInsuranceInfo   {
    insuranceCompany: InsuranceCompany
}

type InsuranceCompany   {
    id: ID!
    name: String!
}

type InsuranceCompanyCollection   {
    insuranceCompanies: [InsuranceCompany!]!
}

type HomeSetInsuranceInfoPayload   {
    insuranceInfo: HomeInsuranceInfo
    errors: [HomeSetInsuranceInfoError!]!
}

type ProjectDescription   {
    projectNumber: String
    orderReferenceNumber: String
    buildingTitle: String
}

enum ConstructionType {
  CONCRETE
  WOOD
  BRICK
  STEEL
  OTHER
}

enum SystemCountry   {
    NO
    SE
    OTHER
}

type Home implements Node   {
    id: ID!
    # will become non-optional after dropping support for deprecated attributes
    locationInfo: HomeLocationInfo
    systemCountry: SystemCountry!
    homeInfo: HomeInfo!
    avatar(uploadFile: String): Avatar
    insuranceInfo: HomeInsuranceInfo

    areas: [Area!]!
    devices(sort: DeviceSortInput, filter: DeviceFilterInput): [Device!]!
    hubs: [Hub!]!
}

type Area implements Node   {
    id: ID!
    areaName: String!
    areaType: AreaType!
    size: Float
    floor: Int
    children: Boolean

    devices(sort: DeviceSortInput, filter: DeviceFilterInput): [Device!]!
    accessPolicies: [HomeProfileActionAccess!]!
}

enum FavoriteSupportedType {
    DEVICE_GROUP
}

type DeviceAccessPolicy   {
    read: Boolean!
    write: Boolean!
    delete: Boolean!

    expiresAt: String
}

type DeviceImage   {
    url: String!
    urlSmall: String!
    urlMedium: String!
    urlLarge: String!
}

enum SortDirection {
    ASC
    DESC
}

enum DeviceSortField {
    FAVORITE_CHANGED_AT
    NAME
    REGISTERED_AT
}

enum HomeSortField {
    CREATED_AT
}

input DeviceSortInput {
    field: DeviceSortField!
    order: SortDirection!
}

input DeviceFilterInput {
    deviceTypes: [DeviceType!]
}

input HomeSortInput {
    field: HomeSortField!
    order: SortDirection!
}

type DeviceRelayConfiguration   {
    supportedDeviceTypes: [DeviceType!]
    endDeviceType: DeviceType
}


enum IoModuleConfiguration {
    BMS
    FIRE_ALARM
    GENERIC
    MOTION_SENSOR
}


type DeviceIoModuleConfiguration   {
    supportedConfigurations: [IoModuleConfiguration!]!
    configuration: IoModuleConfiguration
}


type Device implements Node   {
    id: ID!
    deviceType: DeviceType
    name: String
    serialNumber: String!
    imei: String
    macAddress: String
    ipAddress: String
    roomPlacement: String
    manufacturer: DeviceManufacturer
    deviceTemplate(language: String): DeviceTemplate
    image: DeviceImage
    favorite: Boolean
    favoriteChangedAt: String
    registeredAt: String
    canBeUnregistered: Boolean!
    firmwareVersion: String
    latestFirmware: [DeviceFirmware!]

    relayConfiguration: DeviceRelayConfiguration
    ioModuleConfiguration: DeviceIoModuleConfiguration

    area: Area
    traits: [Trait!]!
    accessPolicy: DeviceAccessPolicy
}

type DeviceFirmware   {
    variant: DeviceFirmwareVariant
    version: String!
    downloadUrl: String!
}

type DeviceManufacturer   {
    id: ID!
    name: String!
    logo: DeviceManufacturerLogo!
}

type DeviceManufacturerLogo   {
    url: String!
    urlSmall: String!
    urlMedium: String!
    urlLarge: String!
}

type DeviceInstructionDescriptionItem   {
    description: String!
    additionalInfo: String
}

type DeviceInstructionItem   {
    description: DeviceInstructionDescriptionItem!
    assetUrl: String!
}

type DeviceTemplateInstructions   {
    installation: [DeviceInstructionItem!]!
    configuration: [DeviceInstructionItem!]!
    help: [DeviceInstructionItem!]!
    connectionAssetUrl: String!
}

type DeviceTemplate implements Node   {
    id: ID!
    deviceType: DeviceType!
    name: String
    primaryPairingMode: PairingMode!
    secondaryPairingModes: [PairingMode!]!
    manufacturer: DeviceManufacturer!
    image: DeviceTemplateImage
    imageWithBg: DeviceTemplateImage
    instructions: DeviceTemplateInstructions!
}

type DeviceTemplateImage   {
    url: String!
    urlSmall: String!
    urlMedium: String!
    urlLarge: String!
}

type DeviceGroup   {
    id: ID!
    devices: [Device!]!
    name: String!
    favorite: Favorite
}

type DeviceGroupUpdatedSubscriptionPayload   {
    id: ID!
    devices: [Device!]!
    name: String!
}

type DeviceGroupCollection {
    deviceGroups: [DeviceGroup!]!
}

type DeviceGroupCommand {
    id: ID!
    state: CommandState!
    commandType: CommandType!
}

type Command   {
    id: ID!
    homeId: ID!
    commandType: CommandType!
    commandState: CommandState!
    triggeredAt: String!
    source: CommandSource
    target: CommandTarget
    deviceIds: [ID!]
}

interface Node {
    id: ID!
}

enum TraitType {
    ARM_DISARM
    BASIC_INFO
    CONNECTION
    ELECTRIC_VEHICLE_CHARGER
    ENABLED_DISABLED
    GATEWAY
    INFO
    LIGHT
    LOCATION
    ON_OFF
    OPEN_CLOSE
    POWER
    POWER_CONTROL
    SENSOR
    SMARTLOCK
    STATUS
    TEMPERATURE_CONTROL
    TEMPERATURE_SETTING
    TEST_MODE
    WARNING_DEVICE
    WATER
}

enum TraitAttributeDataType {
    ALARM_TYPE
    AMPERAGE
    ARM_LEVELS
    BASIC_INFO
    BOOLEAN
    CELSIUS
    CLIMATE_MODE
    CLIMATE_MODES
    COLOR
    DATETIME
    EV_CHARGING_SESSION_DETAILS
    FAULTS
    GATEWAY_CONNECTED
    INDEX
    INTEGER
    KWH
    LOCATION
    MILIVOLT
    PERCENT
    POWER_MODE
    POWER_SOURCE
    POWER_SOURCES
    PPM
    SECONDS
    STATUS_CHARGING
    STRING
    TEST_MODE
    VALVE_INFO
}

enum CommandType   {
    ALARM
    ARM
    BRIGHTNESS
    CHILD_LOCK
    CLIMATE_MODE
    COLOR
    CONNECT
    EV_CHARGE
    EV_CHARGING_SPEED
    FROST_GUARD
    MAXIMUM_FLOOR_TEMPERATURE
    NETWORK_SSID
    NETWORK_CREDENTIALS
    NIGHT_SWITCH
    OPEN_PERCENT
    REGULATOR_MODE
    TEMPERATURE_SETPOINT
    TEMPERATURE_SETPOINT_PERCENTAGE
    TURN_ON
    UNLOCK

    HUB_REGISTER
    HUB_UNREGISTER
    GATEWAY_CONNECTED

    KEEP
    PAIR
    REMOVE
    SCAN

    WATER_TAMPER_MODE_OVERRIDE
    WATER_TAMPER_MODE_RESTORE
}

enum PowerSource {
    BATTERY
    CONSTANT_POWER
    DISPOSABLE_BATTERY @deprecated(reason: "use BATTERY")
    RECHARGEABLE_BATTERY @deprecated(reason: "use BATTERY")
}

enum StatusCharging {
    CHARGING
    DRAINING
    FULL
}

enum PowerMode {
    NORMAL
    PERIODIC_RECEIVAL
    STIMULATED_RECEIVAL
}

enum ClimateMode {
    AUTO
    COOL
    DRY
    ECO
    FAN_ONLY
    HEAT
    HEAT_COOL
    OFF
    ON
    PURIFIER
}

type ArmLevel {
    id: Int!
    description: String!
}

enum AlarmType {
    FIRE
    MAN_OVERBOARD
    NO_ALARM
    SECURITY
    BURGLAR @deprecated(reason: "use SECURITY")
    WATER_LEAK
}

enum HumidityIndicator {
    POOR_LOW
    FAIR
    HEALTHY
    POOR_HIGH
}

enum ValveType {
    BALL
    BALL_ADAPTER
    SOLENOID
    UNKNOWN
}

type TraitFaultStatus   {
    id: String @deprecated(reason: "Introduces no value. Will be removed.")
    name: String
    code: String
    description: String
    consumer: String
    guiPriority: String
}

enum Currency {
    NOK
}

type Trait   {
    traitType: TraitType
    commands: [CommandType!]!
    attributes: [TraitAttribute!]!
}

interface TraitAttributeInterface {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!
}

type TraitAttributeIsArmed implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    isArmed: Boolean!
}

type TraitAttributeAvailableArmLevels implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    availableArmLevels: [ArmLevel!]!
}

type TraitAttributeArmLevel implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    armLevel: Int!
}

type TraitAttributeDisarmDefaultTimeout implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    disarmDefaultTimeout: Int!
}

type TraitAttributeIsConnected implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    isConnected: Boolean!
    reportedAt: String
}

type TraitAttributeHeartbeatInterval implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    heartbeatInterval: Int!
}

type TraitAttributeHeartbeatsThreshold implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    heartbeatsThreshold: Int!
}

type TraitAttributeGatewayConnected implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    ethernetConnected: Boolean
    wifiConnected: Boolean
    cellularConnected: Boolean
}

type TraitAttributeWifiConfigured implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    wifiConfigured: Boolean!
}

type TraitAttributeNetworkSsid implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    networkSsid: String!
}

type TraitAttributeNetworkCredentials implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    networkCredentials: String!
}

type TraitAttributeCellularApn implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    cellularApn: String!
}

type TraitAttributeCellularOperator implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    cellularOperator: String!
}

type TraitAttributeBrightness implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    brightness: Float!
}

type TraitAttributeColor implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    hue: Float
    saturation: Float
}

type TraitAttributeIsOn implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    isOn: Boolean!
}

type TraitAttributeOpenPercent implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    openPercent: Float!
}

type TraitAttributeCurrentPowerSourceLevel implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    currentPowerSourceLevel: Int!
}

type TraitAttributeLowBatteryWarning implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    lowBatteryWarning: Boolean!
}

type TraitAttributeCurrentPowerSource implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    currentPowerSource: PowerSource!
}

type TraitAttributeStatusCharging implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    statusCharging: StatusCharging!
}

type TraitAttributeCurrentPowerMode implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    currentPowerMode: PowerMode!
}

type TraitAttributeAvailablePowerSources implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    availablePowerSources: [String!]!
}

type TraitAttributeBatteryVoltage implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    batteryVoltage: Float!
}

type TraitAttributeMainsVoltage implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    mainsVoltage: Float!
}

type TraitAttributeRunningPowerConsumption implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    runningPowerConsumption: Float!
}

type TraitAttributePriority implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    priority: Int!
}

type TraitAttributeAirQuality implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    airQuality: Int!
}

type TraitAttributeCo2 implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    co2: Int!
}

type TraitAttributeHumidity implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    humidity: Float!
    humidityIndicator: HumidityIndicator!
}

type TraitAttributeTemperature implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    temperature: Float!
}

type TraitAttributeVoc implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    voc: Int!
}

type TraitAttributeIsUnlocked implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    isUnlocked: Boolean!
}

type TraitAttributeChildLock implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    childLock: Boolean!
}

type TraitAttributeFault implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    fault: [TraitFaultStatus!]!
}

type TraitAttributeTemperatureSetpoint implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    temperatureSetpoint: Float
    minSetpoint: Float
    maxSetpoint: Float
}

type TraitAttributeTemperatureSetpointPercentage implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    temperatureSetpointPercentage: Float
    minSetpoint: Float
    maxSetpoint: Float
}


type TraitAttributeAvailableClimateModes implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    availableClimateModes: [ClimateMode!]!
}

type TraitAttributeClimateMode implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    climateMode: ClimateMode!
}

type TraitAttributeMaximumFloorTemperature implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    maximumFloorTemperature: Float!
}

type TraitAttributeFrostGuard implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    frostGuard: Boolean!
}

type TraitAttributeNightSwitch implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    nightSwitch: Boolean!
}

type TraitAttributeRegulatorMode implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    regulatorMode: Boolean!
}

type TraitAttributeHeatingElementActive implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    heatingElementActive: Boolean!
}

type TraitAttributeAlarmSound implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    alarmSound: Boolean!
}

type TraitAttributeAlarm implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    alarm: AlarmType!
    snoozed: Boolean
}

type TraitAttributeWaterDetectorCableConnected implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    waterDetectorCableConnected: Boolean!
}

type TraitAttributeBracket implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    bracket: Boolean!
}

type TraitAttributeWaterValvesConnected implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    waterValvesConnected: Int!
}

type TraitAttributeDisabled implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    disabled: Boolean!
}

type TraitAttributeLocation implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    latitude: Float!
    longitude: Float!
    lastReportedAt: String
}

type TraitAttributeMotionDetected implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    lastMotionDetectedAt: String!
}

type TraitAttributeValveInfo implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    valveType: String! @deprecated(reason: "use typeOfValve")
    typeOfValve: ValveType!
    numValves: Int!
}

enum ElectricVehicleChargerStatus {
    EV_NOT_CONNECTED
    CHARGING_ON
    CHARGING_OFF
    CHARGING_SUSPENDED_EXTERNALLY
    READY_TO_CHARGE
}

type TraitAttributeElectricVehicleCharger implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    status: ElectricVehicleChargerStatus!
    chargingStartedAt: String
    chargingFinishedAt: String
    chargingSessionCost: Float
    kwhCharged: Float
    currency: Currency
}

type TraitAttributeEvChargingSpeed implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    evCurrentAmperage: Int!
    evMinAmperage: Int!
    evMaxAmperage: Int!
}

type TraitAttributeTestMode implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    isOn: Boolean!
    lastTriggeredAt: String
}

type TraitAttributePing implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    ping: String!
}

type TraitAttributeBasicInfo implements TraitAttributeInterface   {
    name: String!
    dataType: TraitAttributeDataType!
    editable: Boolean!

    firmwareVersion: String
    model: String
}


union TraitAttribute =
    TraitAttributeAvailableArmLevels | TraitAttributeIsArmed | TraitAttributeArmLevel | TraitAttributeDisarmDefaultTimeout
    | TraitAttributeIsConnected | TraitAttributeHeartbeatInterval | TraitAttributeHeartbeatsThreshold
    | TraitAttributeGatewayConnected | TraitAttributeWifiConfigured | TraitAttributeNetworkSsid | TraitAttributeNetworkCredentials | TraitAttributeCellularApn | TraitAttributeCellularOperator
    | TraitAttributeBrightness | TraitAttributeColor
    | TraitAttributeIsOn
    | TraitAttributeOpenPercent
    | TraitAttributeCurrentPowerSourceLevel | TraitAttributeLowBatteryWarning | TraitAttributeCurrentPowerSource
    | TraitAttributeStatusCharging | TraitAttributeCurrentPowerMode | TraitAttributeAvailablePowerSources | TraitAttributeBatteryVoltage | TraitAttributeMainsVoltage
    | TraitAttributeRunningPowerConsumption | TraitAttributePriority
    | TraitAttributeAirQuality | TraitAttributeCo2 | TraitAttributeHumidity | TraitAttributeTemperature | TraitAttributeVoc
    | TraitAttributeIsUnlocked | TraitAttributeChildLock
    | TraitAttributeFault
    | TraitAttributeTemperatureSetpoint | TraitAttributeTemperatureSetpointPercentage
    | TraitAttributeAvailableClimateModes | TraitAttributeClimateMode | TraitAttributeMaximumFloorTemperature
    | TraitAttributeFrostGuard | TraitAttributeNightSwitch | TraitAttributeRegulatorMode | TraitAttributeHeatingElementActive
    | TraitAttributeAlarmSound | TraitAttributeAlarm
    | TraitAttributeWaterDetectorCableConnected | TraitAttributeWaterValvesConnected | TraitAttributeBracket
    | TraitAttributeDisabled
    | TraitAttributeLocation
    | TraitAttributeMotionDetected
    | TraitAttributeValveInfo
    | TraitAttributeElectricVehicleCharger | TraitAttributeEvChargingSpeed
    | TraitAttributeTestMode
    | TraitAttributePing
    | TraitAttributeBasicInfo


enum AlarmNotificationStatus {
    DELIVERED
    DISMISSED
    FAILED
    REQUESTED
}

type EmergencyContactsAlertAlarmNotificationInactive   {
    reason: String
}

type EmergencyContactsAlertAlarmNotificationTriggerCountdown   {
    alertTriggersAt: String!
}

type EmergencyContactsAlertAlarmNotification   {
    status: AlarmNotificationStatus!
}

type EmergencyContactsImOkAlarmNotification   {
    status: AlarmNotificationStatus!
}

union AlarmNotification =
    EmergencyContactsAlertAlarmNotificationInactive
    | EmergencyContactsAlertAlarmNotificationTriggerCountdown
    | EmergencyContactsAlertAlarmNotification
    | EmergencyContactsImOkAlarmNotification


type AlarmNotificationLifecycle   {
    id: ID!
    notifications: [AlarmNotification!]!
}

enum AlarmStationNotificationStatus {
    DELIVERED
    FAILED
    REQUESTED
}

enum AlarmStationDeviceEventType {
    ACTIVATED
    CANCELLED
    TEST_MODE_SIGNAL
}

type AlarmStationDeviceEvent   {
    triggeredAt: String!
    eventType: AlarmStationDeviceEventType!
    status: AlarmStationNotificationStatus!
}

type AlarmStationDeviceEventLifecycle   {
    deviceId: ID!
    events: [AlarmStationDeviceEvent!]!
}

type AlarmStationNotificationLifecycle   {
    deviceEvents: [AlarmStationDeviceEventLifecycle!]!
}


enum AlarmState {
    ALARM
    CLEARED
    SNOOZED  # not supported for some subtypes
}

interface AlarmInterface {
    id: ID!
    state: AlarmState!
    triggeredAt: String
    snoozeExpiresAt: String  @deprecated(reason: "not supported for some subtypes")
    areas: [Area!]!
    notificationLifecycle: AlarmNotificationLifecycle
    alarmStationNotificationLifecycle: AlarmStationNotificationLifecycle
}

# deprecated !!
type BurglarAlarm implements AlarmInterface   {
    id: ID!
    state: AlarmState!
    triggeredAt: String
    snoozeExpiresAt: String  @deprecated(reason: "not supported for this type - always returns Null")
    areas: [Area!]!
    notificationLifecycle: AlarmNotificationLifecycle
    alarmStationNotificationLifecycle: AlarmStationNotificationLifecycle
}

type SecurityAlarm implements AlarmInterface   {
    id: ID!
    state: AlarmState!
    isArmed: Boolean!
    triggeredAt: String
    snoozeExpiresAt: String  @deprecated(reason: "not supported for this type - always returns Null")
    areas: [Area!]!
    notificationLifecycle: AlarmNotificationLifecycle
    alarmStationNotificationLifecycle: AlarmStationNotificationLifecycle
}

type ManOverboardAlarm implements AlarmInterface   {
    id: ID!
    state: AlarmState!
    triggeredAt: String
    snoozeExpiresAt: String  @deprecated(reason: "not supported for this type - always returns Null")
    areas: [Area!]!
    notificationLifecycle: AlarmNotificationLifecycle
    alarmStationNotificationLifecycle: AlarmStationNotificationLifecycle
}

type FireAlarm implements AlarmInterface   {
    id: ID!
    state: AlarmState!
    triggeredAt: String
    snoozeExpiresAt: String  @deprecated(reason: "not supported for this type - always returns Null")
    areas: [Area!]!
    notificationLifecycle: AlarmNotificationLifecycle
    alarmStationNotificationLifecycle: AlarmStationNotificationLifecycle
}

type WaterAlarm implements AlarmInterface   {
    id: ID!
    state: AlarmState!
    triggeredAt: String
    snoozeExpiresAt: String
    areas: [Area!]!
    notificationLifecycle: AlarmNotificationLifecycle
    alarmStationNotificationLifecycle: AlarmStationNotificationLifecycle
}

# BurglarAlarm is deprecated, use SecurityAlarm instead
union Alarm = WaterAlarm | FireAlarm | BurglarAlarm | SecurityAlarm | ManOverboardAlarm

enum CollectiveAlarmState {
    ALARM
    CLEARED
}

interface CollectiveAlarmInterface {
    id: ID!
    state: CollectiveAlarmState!
}

type CollectiveFireAlarm implements CollectiveAlarmInterface   {
    id: ID!
    state: CollectiveAlarmState!
    triggeredAt: String
    originLocation: CollectiveAlarmOriginLocation
    evacuationInstructions: EvacuationInstructions!
}

union CollectiveAlarm = CollectiveFireAlarm

type CollectiveAlarmCollection   {
    alarms: [CollectiveAlarm!]!
}

type UnitAlarmOriginLocation   {
    unitNumber: String!
    apartmentNumber: String!
}

type CommonAreaAlarmOriginLocation   {
    nickname: String!
}

union CollectiveAlarmOriginLocation = UnitAlarmOriginLocation | CommonAreaAlarmOriginLocation

type EvacuationInstructions   {
    evacuationPoint: EvacuationPoint!
}

type EvacuationPoint   {
    mapImage: ImageUrl
}

type HousingAssociation {
    id: ID!
    buildings: [Building!]!
    collectiveAlarmZones: [CollectiveAlarmZone!]!
}

type CollectiveAlarmZone {
    id: ID!
    facilities: [Facility!]!
    configurations: [CollectiveAlarmZoneConfiguration!]!
}

type Building {
    id: ID!
    units: [Unit!]!
    commonAreas: [CommonArea!]!
}

type Unit {
    id: ID!
    unitNumber: String
}

type CommonArea {
    id: ID!
    nickname: String!
}

union CollectiveAlarmZoneConfiguration = CollectiveFireAlarmConfiguration
union Facility = Building | Unit | CommonArea

type CollectiveFireAlarmConfiguration {
    propagationDelaySeconds: Int!
    meetingPointMap(uploadFile: String): ImageInfo
}

enum FacilityType {
    BUILDING
    UNIT
    COMMON_AREA
}

input ZoneAddFacilityInput {
    facilityType: FacilityType!
    facilityId: ID!
}

input FireAlarmZoneConfigurationInput {
    propagationDelaySeconds: Int
}

input CollectiveAlarmZoneConfigurationInput {
    fireAlarmZoneConfigurationInput: FireAlarmZoneConfigurationInput
}

type HousingAssociationCollectiveAlarmCreateZonePayload {
    collectiveAlarmZone: CollectiveAlarmZone
    errors: [HousingAssociationCollectiveAlarmCreateZoneError!]!
}

type HousingAssociationCollectiveAlarmDeleteZonePayload {
    errors: [HousingAssociationCollectiveAlarmDeleteZoneError!]!
}

type HousingAssociationCollectiveAlarmConfigureZonePayload {
    collectiveAlarmZone: CollectiveAlarmZone
    errors: [HousingAssociationCollectiveAlarmConfigureZoneError!]!
}

type HousingAssociationCollectiveAlarmZoneAddFacilityPayload {
    collectiveAlarmZone: CollectiveAlarmZone
    errors: [HousingAssociationCollectiveAlarmZoneAddFacilityError!]!
}

type HousingAssociationCollectiveAlarmZoneRemoveFacilityPayload {
    collectiveAlarmZone: CollectiveAlarmZone
    errors: [HousingAssociationCollectiveAlarmZoneRemoveFacilityError!]!
}

type HousingAssociationBuildingAddFacilityTempPayload {
    errors: [HousingAssociationBuildingAddFacilityTempError!]!
}

type HousingAssociationBuildingRemoveFacilityTempPayload {
    errors: [HousingAssociationBuildingRemoveFacilityTempError!]!
}

type CollectiveAlarmCreatePayload  {
    errors: [CollectiveAlarmCreateError!]!
}
type CollectiveAlarmDeletePayload  {
    errors: [CollectiveAlarmDeleteError!]!
}
type CollectiveAlarmSetTenantsPayload  {
    errors: [CollectiveAlarmSetTenantsError!]!
}

enum HubWaterGuardMode {
    NORMAL
    NO_VALVE
    OVERRIDDEN
    RESTORED
    TAMPER_WARNING
    TAMPERED
}

type HubWaterGuard   {
    wasWaterSensorTapePreviouslyConnected: Boolean!
    mode: HubWaterGuardMode!
    tamperModeWarningTriggeredAt: String
    tamperModeTriggersAt: String
    overrideModeTriggeredAt: String
    showLevel1Warning: Boolean!
    showLevel2Warning: Boolean!
}

type HubTemplate   {
    id: ID!
    name: String!

    hubAssetUrl: String!
    hubWithBgAssetUrl: String!
    hubQrCodeAssetUrl: String!
    hubConnectionAssetUrl: String!
    hubSearchAssetUrl: String!
    waterLeakDetectorAssetUrl: String!
    waterLeakDetectorInstructionsAssetUrl: String!
    waterLeakDetectorHelpAssetUrl: String!
    waterSensorTapeAssetUrl: String!
    waterSensorTapeInstructionsAssetUrl: String!
    waterLeakSystemPressHubButtonAssetUrl: String!
    sintefLogoAssetUrl: String!
}

type Hub   {
    id: ID!
    name: String
    hubType: HubType
    productType: HubProductType
    brandName: String
    firmwareVersion: String
    serialNumber: String
    macAddress: String!
    manufacturerInformation: String
    wasWaterSensorTapePreviouslyConnected: Boolean! @deprecated(reason: "use waterGuard")
    waterGuard: HubWaterGuard!
    hubTemplate: HubTemplate!

    area: Area
    devices(sort: DeviceSortInput, filter: DeviceFilterInput): [Device!]!
    repeaters: [Hub!]!
    traits: [Trait!]!
}

type HubInfo   {
    id: ID!
    firmwareVersion: String
    serialNumber: String!
    registered: Boolean!
    homeToClaim: ID
    homeId: ID @deprecated(reason: "use homeToClaim")
}

type DeviceInfo {
    id: ID!
    macAddress: String!
    firmwareVersion: String
    serialNumber: String!
    registered: Boolean!
}

enum NotificationSource {
    UNSPECIFIED
    ALARMS
    WATER_LEAK_ALARM
    FIRE_ALARM
    SECURITY_ALARM
    WATER_GUARD
    DEVICE
}

enum NotificationKind {
    UNSPECIFIED
    SUCCESS
    INFO
    WARNING
    ERROR
    CRITICAL
    REMINDER
}

type NotificationContext {
    kind: NotificationKind!
    source: NotificationSource!
}

type NotificationMessage {
    title: String!
    body: String!
}

type InboxNotification {
    id: ID!
    message: NotificationMessage!
    deepLink: String
    receivedAt: String!
    read: Boolean!
    context: NotificationContext!
}

type InboxNotificationCollection {
    notifications: [InboxNotification!]!
}

enum AreaType {
    BATHROOM
    BEDROOM
    DINING_ROOM
    FAMILY_ROOM
    GARAGE
    GUEST_ROOM
    HALLWAY
    HOME_OFFICE
    KITCHEN
    LAUNDRY_ROOM
    LIVING_ROOM
    STORAGE_ROOM
    TECHNICAL_ROOM
    TV_ROOM
    WALK_IN_CLOSET
}

enum HomeType {
    APARTMENT
    COMMON_AREA
    COTTAGE
    HOUSE
    ROW_HOUSE
    TOWN_HOUSE
    VESSEL
}

enum HomeDwellingUnit {
    SDU
    MDU
}

enum HeatingType {
    AIR_TO_AIR_HEATPUMP
    AIR_TO_WATER_HEATPUMP
    DISTRICT_HEATING
    ELECTRICITY
    ELECTRIC_BOILER
    GROUND_SOURCE
    OTHER
}

enum CoolingType {
    AC
    OTHER
}

enum DeviceType   {
    AIR_QUALITY_SENSOR
    COOLING
    COLOR_LIGHT
    DIMMABLE_LIGHT
    DOOR_BELL
    DOOR_LOCK
    DOOR_WINDOW_DETECTOR
    ELECTRIC_CAR_CHARGER
    EMI_HAN
    HEATING
    HUMIDITY_SENSOR
    IO_MODULE
    KEY_PAD
    LIGHT
    MOTION_SENSOR
    MULTISENSOR
    OTHER
    SMART_CABLE
    SMART_PLUG
    SMART_RELAY
    SMART_SWITCH
    SMOKE_DETECTOR
    THERMOSTAT
    VENTILATION
    VESSEL_FOB
    VIDEO_CAMERA
    WATER_HEATER
    WATER_LEAK_DETECTOR
    WATER_SENSOR_TAPE
    WATER_VALVE
}

enum DeviceFirmwareTransportMedium   {
    BLE
    ZIGBEE
}

enum DeviceFirmwareVariant   {
    ROUTER
}

enum PairingMode {
    PLUG
    SCANNING
    QR_CODE
}

enum HomeMemberInviteMethod {
    EMAIL
    QR_CODE
    SMS
}

enum HomeMemberRole   {
    REGULAR
    ADMIN
}
enum HomeMemberInvitationStatus   {
    ACCEPTED
    ACTIVE
    REJECTED
    REVOKED
}

enum HomeProfileActionType {
    ALARMS_AND_NOTIFICATIONS
    ALARM_SERVICES
    ANALYTICS
    APP_SETTINGS
    BURGLAR_ALARM
    DEVICE_MANAGEMENT
    DOOR_LOCK
    EVENTS
    FIRE
    HOME_CONTROL
    HOME_MANAGEMENT
    ROUTINES
    SETUP
    USER_MANAGEMENT
    WATER_LEAKAGE_SYSTEM
}

enum HubType {
    GATEWAY
    REPEATER
}

enum HubProductType {
    HUB_4G
    HUB_WIFI
    HUB_SAFEBOAT_4G
}

enum CommandState   {
    FAILED
    PENDING
    RUNNING
    SUCCESS
}

enum CommandSource {
    CUSTOMER
    DEMAND_RESPONSE
    SMART_ENERGY
    ROUTINE
}

enum CommandTriggerMeta {
    OVERRIDE
    RESTORE
}

enum CommandTarget {
    DEVICE
    DEVICE_GROUP
}

# Stats - Energy Summary
enum EnergyConsumptionActualVsAverageComparison {
    LESS_THAN_AVERAGE
    MORE_THAN_AVERAGE
}

type EnergyRelativeConsumption {
    consumptionUnit: EnergyUnit!
    mostEfficientConsumption: Float!
    averageConsumption: Float!
    leastEfficientConsumption: Float!
    actualConsumption: Float!
    actualVsAverageConsumptionComparison: EnergyConsumptionActualVsAverageComparison!
    actualVsAverageConsumptionPercent: Float!
}

type EnergyStatsSummaryPayload {
    relativeConsumption: EnergyRelativeConsumption
    errors: [EnergyStatsSummaryError!]!
}

enum PushNotificationChannel {
    GCM
    APNS
}

input PushNotificationEndpointInput {
    address: String!
    channel: PushNotificationChannel!
}

type PushNotificationEndpointSetPayload {
    errors: [PushNotificationEndpointSetError!]!
}

type NotificationInboxMarkAsReadPayload {
    errors: [NotificationInboxMarkAsReadError!]!
}

enum TriggerTypeInput   {
    SINGLE_CONDITION
}

enum ConditionTypeInput   {
    SPECIFIC_TIME_CONDITION
    SPECIFIC_TIME_PERIOD_CONDITION
    TIME_OF_DAY_CONDITION
    TIME_OF_DAY_PERIOD_CONDITION
}

enum ActionTypeInput   {
    DEVICE_COMMAND_REVERT
    DEVICE_COMMAND
}

# Internally this input is typed using a Union, however GQL does not support unions for input types
# thus we have to use a single input type with all possible inputs, where only the discriminator field
# is required, and just one input shall be provided.
input TriggerConditionInput {
    type: ConditionTypeInput!
    specificTimeCondition: SpecificTimeConditionInput
    specificTimePeriodCondition: SpecificTimePeriodConditionInput
    timeOfDayPeriodCondition: TimeOfDayPeriodConditionInput
    timeOfDayCondition: TimeOfDayConditionInput
}

input RoutineTriggerInput {
    triggerType: TriggerTypeInput!
    conditions: [TriggerConditionInput!]!
}

# check docs for RoutineTriggerInput - same rules apply
input RoutineActionInput {
    actionType: ActionTypeInput!
    commandType: CommandType
    commandPayload: String
}

input RoutineLogicInput {
    trigger: RoutineTriggerInput!
    action: RoutineActionInput!
    compensatingAction: RoutineActionInput
}

input RoutineDescriptionInput {
    name: String!
    description: String
}

input RoutineOriginInput {
    type: RoutineOriginType!
    source: RoutineOriginSource
}

input RoutineCreateInput {
    logic: RoutineLogicInput!
    description: RoutineDescriptionInput!
}

input RoutineCreateInternalInput {
    logic: RoutineLogicInput!
    origin: RoutineOriginInput!
}

input RoutineUpdateDescriptionInput {
    name: String
    description: String
}

input RoutineUpdateInput {
    logic: RoutineLogicInput!
}

type RoutineCreatePayload   {
    routineId: ID
    errors: [RoutineCreateError!]!
}

type RoutineActivatePayload   {
    errors: [RoutineActivateError!]!
}

type RoutineDeactivatePayload   {
    errors: [RoutineDeactivateError!]!
}

type RoutineDeletePayload   {
    errors: [RoutineDeleteError!]!
}

type RoutineUpdateDescriptionPayload   {
    routine: Routine
    errors: [RoutineUpdateDescriptionError!]!
}

type RoutineUpdatePayload   {
    routine: Routine
    errors: [RoutineUpdateError!]!
}

enum RoutineState   {
    ACTIVE
    ACTIVATING
    INACTIVE
    DEACTIVATING
}

enum DayOfWeek   {
    MONDAY
    TUESDAY
    WEDNESDAY
    THURSDAY
    FRIDAY
    SATURDAY
    SUNDAY
}

input TimeOfDayInput {
    minute: Int!
    hour: Int!
}

type TimeOfDay   {
    minute: Int!
    hour: Int!
}

input SpecificTimeConditionInput {
    at: String!
}

type SpecificTimeCondition   {
    at: String!
}

input TimeOfDayPeriodConditionInput {
    startTime: TimeOfDayInput!
    endTime: TimeOfDayInput!
    onDays: [DayOfWeek!]!
}

type TimeOfDayPeriodCondition   {
    startTime: TimeOfDay!
    endTime: TimeOfDay!
    onDays: [DayOfWeek!]!
}

input TimeOfDayConditionInput {
    atTime: TimeOfDayInput!
    onDays: [DayOfWeek!]!
}

type TimeOfDayCondition   {
    atTime: TimeOfDay!
    onDays: [DayOfWeek!]!
}

input SpecificTimePeriodConditionInput {
    startAt: String!
    endAt: String!
}

type SpecificTimePeriodCondition   {
    startAt: String!
    endAt: String!
}

# preview - not implemented
type AllConditions   {
    conditions: [TriggerCondition!]!
}

# preview - not implemented
type AnyCondition   {
    conditions: [TriggerCondition!]!
}

type SingleCondition   {
    condition: TriggerCondition!
}

type SetEvChargingAction   {
    deviceId: ID!
    chargingOn: Boolean!
}

type TurnOnAction   {
    deviceId: ID!
    isOn: Boolean!
}

type RevertPreviousAction   {
    revert: Boolean!
}

union TriggerCondition = SpecificTimeCondition | SpecificTimePeriodCondition | TimeOfDayPeriodCondition | TimeOfDayCondition
union RoutineTrigger = SingleCondition  # | AnyCondition | AllConditions
union RoutineAction = SetEvChargingAction | TurnOnAction | RevertPreviousAction

type RoutineLogic   {
    trigger: RoutineTrigger!
    action: RoutineAction!
    compensatingAction: RoutineAction
}

type RoutineDescription   {
    name: String!
    description: String
}

enum RoutineOriginType    {
    CUSTOM
    SYSTEM
}

enum RoutineOriginSource   {
    DEMAND_RESPONSE
}

type RoutineOrigin   {
    type: RoutineOriginType!
    source: RoutineOriginSource
}

type Routine   {
    id: ID!
    logic: RoutineLogic!
    state: RoutineState!
    origin: RoutineOrigin!
    description: RoutineDescription
}

type RoutineCollection   {
    routines: [Routine!]!
}

# Errors
interface PayloadError {
    message: String!
    path: String!
}

type AlarmDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

type AlarmOperationNotSupportedError implements PayloadError {
    message: String!
    path: String!
}

type AlreadyArmedError implements PayloadError {
    message: String!
    path: String!
}
type AlreadyDisarmedError implements PayloadError {
    message: String!
    path: String!
}

type AlarmAlertNotDeliveredError implements PayloadError {
    message: String!
    path: String!
}

type AlarmActiveError  implements PayloadError {
    message: String!
    path: String!
}


type AlarmNotActiveError implements PayloadError {
    message: String!
    path: String!
}


type AlarmAlertNotificationAlreadyRequestedError implements PayloadError {
    message: String!
    path: String!
}

type AlarmAlertNotificationDismissedError implements PayloadError {
    message: String!
    path: String!
}

type AlarmImOkNotificationAlreadyRequestedError implements PayloadError {
    message: String!
    path: String!
}

type HomeAddressAlreadyExists implements PayloadError {
    message: String!
    path: String!
}

type HomeInvalidUnitNumberError implements PayloadError   {
    message: String!
    path: String!
}

type UserDoesNotExistError implements PayloadError   {
    message: String!
    path: String!
}

type DeletionFailedError implements PayloadError {
    message: String!
    path: String!
}

type GeofenceAlreadyActivatedError implements PayloadError {
    message: String!
    path: String!
}

type GeofenceDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

type InvalidFirstName implements PayloadError   {
    message: String!
    path: String!
}

type InvalidLastName implements PayloadError   {
    message: String!
    path: String!
}

type InvalidPhoneNumber implements PayloadError   {
    message: String!
    path: String!
}

type LocaleNotSupported implements PayloadError {
    message: String!
    path: String!
}

type HomeDoesNotExistError implements PayloadError   {
    message: String!
    path: String!
}

type HomeMemberDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

type RemoveTheOwnerAttemptError implements PayloadError{
    message: String!
    path: String!
}

type InvitationDoesNotExistError implements PayloadError   {
    message: String!
    path: String!
}

type CampaignDoesNotExistError implements PayloadError   {
    message: String!
    path: String!
}

type HomeMemberWithGivenEmailAlreadyExists implements PayloadError {
    message: String!
    path: String!
}

type UserAlreadyMemberInHome implements PayloadError {
    message: String!
    path: String!
}

type HomeMemberAlreadyInvitedError implements PayloadError {
    message: String!
    path: String!
}

type MissingEmailError implements PayloadError   {
    message: String!
    path: String!
}

type AlreadyInvitedError implements PayloadError   {
    message: String!
    path: String!
}

type HomeMemberInvitationMissingPhoneNumber implements PayloadError {
    message: String!
    path: String!
}

type MissingPhoneNumber implements PayloadError   {
    message: String!
    path: String!
}

type InvitationExpiredError implements PayloadError   {
    message: String!
    path: String!
}

type InvitationInactiveError implements PayloadError   {
    message: String!
    path: String!
}

type InvitationAlreadyAcceptedError implements PayloadError   {
    message: String!
    path: String!
}

type InvitationStillActiveError implements PayloadError {
    message: String!
    path: String!
}

type AreaDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

type AreaNameAlreadyExistsError implements PayloadError {
    message: String!
    path: String!
}

type CommandDoesNotExistError implements PayloadError   {
    message: String!
    path: String!
}

type CommandNotSentError implements PayloadError   {
    message: String!
    path: String!
}

type InvalidDeviceIdError implements PayloadError {
    message: String!
    path: String!
}

type HubDoesNotExistError implements PayloadError   {
    message: String!
    path: String!
}

type HubProvisioningLimitExceededError implements PayloadError  {
    message: String!
    path: String!
}

type HubRegistryNotCompleteError implements PayloadError  {
    message: String!
    path: String!
    missingField: String!
}

type HubCommandExecutionError  {
    path: String!
    message: String!
}

type HubCommandExecutionResponse  {
    errors: [HubCommandError!]!
}

type HubNotInAreaError implements PayloadError {
    message: String!
    path: String!
}

type HubAlreadyRegisteredError implements PayloadError {
    message: String!
    path: String!
}

type HubNotRegisteredError implements PayloadError   {
    message: String!
    path: String!
}

type HubRegistrationFailedError implements PayloadError {
    message: String!
    path: String!
}

type HubRegistrationDevicesError implements PayloadError   {
    message: String!
    path: String!
}

type HubScanFoundDevicesError implements PayloadError   {
    message: String!
    path: String!
}

type HubKeepDevicesFinishedError implements PayloadError   {
    message: String!
    path: String!
}

type HubUnregistrationFailedError implements PayloadError   {
    message: String!
    path: String!
}

type HubWaterGuardNotInTamperModeError implements PayloadError   {
    message: String!
    path: String!
}

type HubWaterGuardNotInTamperWarningModeError implements PayloadError {
    message: String!
    path: String!
}

type HubWaterGuardTamperWarningModeNothingToResolveError implements PayloadError {
    message: String!
    path: String!
}

type HubInvalidHomeKitSetupPayloadError implements PayloadError {
    message: String!
    path: String!
}

type DeviceDoesNotExistError implements PayloadError   {
    message: String!
    path: String!
}

type DeviceNotRegisteredError implements PayloadError   {
    message: String!
    path: String!
}

type RelayEndDeviceTypeNotSupportedError implements PayloadError {
    message: String!
    path: String!
}

type IoModuleConfigurationNotSupportedError implements PayloadError {
    message: String!
    path: String!
}

type RelayConfigurationNotSupportedError implements PayloadError {
    message: String!
    path: String!
}

type CanNotUnregisterInternalDeviceError implements PayloadError   {
    message: String!
    path: String!
}

type InternalDeviceStillConnectedError implements PayloadError   {
    message: String!
    path: String!
}

type DeviceAlreadyRegisteredError implements PayloadError {
    message: String!
    path: String!
}

type DeviceNotInAreaError implements PayloadError {
    message: String!
    path: String!
}

type DeviceMaxCountPerHubExceededError implements PayloadError {
    message: String!
    path: String!
}

type InvalidSerialNumberFormatError implements PayloadError   {
    message: String!
    path: String!
}

type UnknownQrCodeFormatError implements PayloadError {
    message: String!
    path: String!
}

type UnknownDeviceManufacturerError implements PayloadError {
    message: String!
    path: String!
}

type UnknownDeviceTypeError implements PayloadError {
    message: String!
    path: String!
}

type UnknownError implements PayloadError {
    message: String!
    path: String!
}

type TraitNotSupportedError implements PayloadError {
    message: String!
    path: String!
}

type TraitNotSupportedForDeviceError implements PayloadError   {
    message: String!
    path: String!
}

type DeviceCommandInvalidInputError implements PayloadError   {
    message: String!
    path: String!
}

type TraitUpdateFailedError implements PayloadError   {
    message: String!
    path: String!
}

type EmailAlreadyVerifiedError implements PayloadError {
    message: String!
    path: String!
}

type UnknownDeviceError implements PayloadError {
    message: String!
    path: String!
}

type ClimateModeNotAvailableError implements PayloadError {
    message: String!
    path: String!
}

type InvalidRangeTimeSeriesError implements PayloadError {
    message: String!
    path: String!
}

type InvalidGranularityTimeSeriesError implements PayloadError {
    message: String!
    path: String!
}

type MissingParameterTimeSeriesError implements PayloadError {
    message: String!
    path: String!
}

type TagNotUniqueTimeSeriesError implements PayloadError {
    message: String!
    path: String!
}

type UnknownMarketBalanceAreaError implements PayloadError {
    message: String!
    path: String!
}

type MissingMeteringPointsError implements PayloadError {
    message: String!
    path: String!
}

type VATValueNotFoundError implements PayloadError {
    message: String!
    path: String!
}

type InvitationTokenExpiredError implements PayloadError{
    message: String!
    path: String!
}

type RoleCouldNotBeChangedError implements PayloadError{
    message: String!
    path: String!
}

type InvitationTokenInvalidError implements PayloadError   {
    message: String!
    path: String!
}

type InvitationSendingEmailNotPossible implements PayloadError   {
    message: String!
    path: String!
}

type InvitationSendingSmsNotPossible implements PayloadError   {
    message: String!
    path: String!
}

# Error can appear in the errors array multilpe times - path holds the meter_id
type ElhubInvalidEnergyMeter implements PayloadError {
    message: String!
    path: String!
}

# deprecated: use ElhubInvalidEnergyMeter
type ElhubInvalidEnergyMeters implements PayloadError {
    message: String!
    path: String!
    invalidEnergyMeterIds: [String!]! @deprecated(reason: "field does not work")
}

# Error can appear in the errors array multilpe times - path holds the meter_id
type ElhubMeterAlreadyRegistered implements PayloadError {
    message: String!
    path: String!
}

# Error can appear in the errors array multilpe times - path holds the meter_id
type ElhubMeterRequiresAuthorization implements PayloadError {
    message: String!
    path: String!
}

type ElhubAlreadyConnected implements PayloadError {
    message: String!
    path: String!
    registeredEnergyMeterIds: [String!]! @deprecated(reason: "field does not work")
}

type ElhubNotConnected implements PayloadError {
    message: String!
    path: String!
}


type DataNotAvailableError implements PayloadError {
    message: String!
    path: String!
}

type UnableToSetPushNotificationEndpointError implements PayloadError {
    message: String!
    path: String!
}

type NotificationDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

type SubscriptionInactiveError implements PayloadError {
    message: String!
    path: String!
}

type AlarmStationAlreadyDisabledError implements PayloadError {
    message: String!
    path: String!
}

type AlarmStationActiveAlarmError implements PayloadError {
    message: String!
    path: String!
}

type AlarmStationAlreadyEnabledError implements PayloadError {
    message: String!
    path: String!
}

type AlarmStationMissingHomeInfoError implements PayloadError {
    message: String!
    path: String!
}

type AlarmStationMissingUserInfoError implements PayloadError {
    message: String!
    path: String!
}

type AlarmStationCountryNotSupportedError implements PayloadError {
    message: String!
    path: String!
}

type AlarmStationInvalidPostalCodeError implements PayloadError {
    message: String!
    path: String!
}

type AlarmStationDisabledError implements PayloadError {
    message: String!
    path: String!
}

type AlarmStationTooManyEmergencyContactsError implements PayloadError {
    message: String!
    path: String!
}

type AlarmStationEmergencyContactAlreadyAddedError implements PayloadError {
    message: String!
    path: String!
}

type AlarmStationEmergencyContactDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

type CollectiveAlarmZoneDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

type CollectiveAlarmAlreadyExistsError implements PayloadError {
    message: String!
    path: String!
}

type CollectiveAlarmDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

interface UpdatePayloadInterface {
    # partyId: ID!
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
}

enum UpdatedAction {
    ADDED
    UPDATED
    REMOVED
}

type DeviceUpdatedPayload   {
    # partyId: ID!
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
    deviceId: ID!
    device: Device!
}

type DeviceUpdatePayload implements UpdatePayloadInterface   {
    # partyId: ID!
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
    deviceId: ID!
    device: Device!
}

type AreaUpdatedPayload implements UpdatePayloadInterface   {
    # partyId: ID!
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
    areaId: ID!
    area: Area!
}

type MemberUpdatedPayload implements UpdatePayloadInterface   {
    # partyId: ID!
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
    memberId: ID!
    member: HomeMember  # optional because it cannot be returned when removed
}

type MemberInvitationUpdatedPayload implements UpdatePayloadInterface   {
    # partyId: ID!
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
    invitationId: ID!
    invitation: HomeMemberInvitation!
}

type CloudConnectionUpdatedPayload implements UpdatePayloadInterface   {
    # partyId: ID!
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
    providerId: ID!
    cloudConnection: CloudConnection!
}

type AlarmStationInfoUpdatePayload implements UpdatePayloadInterface   {
    # partyId: ID!
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
    alarmStationInfo: AlarmStationInfo!
}

type DeviceGroupUpdatedPayload implements UpdatePayloadInterface   {
    # partyId: ID!
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
    deviceGroupId: ID!
    deviceGroup: DeviceGroupUpdatedSubscriptionPayload
}

type FreezeProtectionUpdatedPayload implements UpdatePayloadInterface   {
    # partyId: ID!
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
    freezeProtection: FreezeProtection
}

type SmartEnergyUpdatedPayload implements UpdatePayloadInterface   {
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
    smartEnergy: SmartEnergy
}

type CollectiveAlarmUpdatedPayload implements UpdatePayloadInterface   {
    partyId: ID  # temporarily made non-required, until we will introduce full-blown notification service
    homeId: ID!
    action: UpdatedAction
    collectiveAlarm: CollectiveAlarm
}

type DemandResponseUpdatedPayload   {
    userId: ID!
    action: UpdatedAction
    demandResponse: DemandResponse
}

type RoutineUpdatedPayload   {
    homeId: ID!
    action: UpdatedAction
    routine: Routine
}

type AccountUpdatedPayload   {
    userId: ID!
    action: UpdatedAction
    account: Account
}


type FreezeProtectionActivation   {
    triggeredAt: String!
    canSafelyOpenValve: Boolean!
}

type FreezeProtection   {
    enabled: Boolean!
    thresholdTemperature: Float!
    temperatureSensors: [Device!]!
    activation: FreezeProtectionActivation
}

input FreezeProtectionConfigureInput {
    enabled: Boolean
    thresholdTemperature: Float
    temperatureSensors: [ID!]
}

type FreezeProtectionConfigurePayload {
    freezeProtection: FreezeProtection
    errors: [FreezeProtectionConfigureError!]!
}

type DemandResponseEnrollPayload {
    errors: [DemandResponseEnrollError!]!
}

type DemandResponseUnenrollPayload {
    errors: [DemandResponseUnenrollError!]!
}

type SmartEnergyEnablePayload {
    errors: [SmartEnergyEnableError!]!
}

type SmartEnergyDisablePayload {
    errors: [SmartEnergyDisableError!]!
}

type SmartEnergySetHourlyLimitPayload {
    errors: [SmartEnergySetHourlyLimitError!]!
}

type SmartEnergyEnableDevicePayload {
    errors: [SmartEnergyEnableDeviceError!]!
}

type SmartEnergyDisableDevicePayload {
    errors: [SmartEnergyDisableDeviceError!]!
}

type InstallerOrganizationDashboard {
    organization: InstallerOrganization!
    role: InstallerOrganizationRole!
}

type InstallerDashboard {
    projects: InstallerProjectCollection
    organization: InstallerOrganizationDashboard
}

type TransferredProjectArea {
    areaName: String!
    areaType: AreaType!
}

type TransferredProjectHub {
    area: TransferredProjectArea
}

type TransferredProjectDevice {
    area: TransferredProjectArea
    deviceType: DeviceType!
}

interface ProjectInterface {
    id: ID!
    installerId: ID
    status: ProjectStatus!
    avatar(uploadFile: String): ImageInfo
}

enum ProjectStatus {
    FINISHED
    IN_PROGRESS
}

type TransferredProject implements ProjectInterface   {
    id: ID!
    installerId: ID
    status: ProjectStatus!
    avatar(uploadFile: String): ImageInfo
    buildingType: HomeType
    buildingYear: Int
    buildingSize: Float
    locationInfo: HomeLocationInfo
    constructionType: ConstructionType
    description: ProjectDescription!
    hubs: [TransferredProjectHub!]!
    devices: [TransferredProjectDevice!]!
}

type OngoingProject implements ProjectInterface   {
    id: ID!
    installerId: ID
    status: ProjectStatus!
    avatar(uploadFile: String): ImageInfo
    home: Home!
    devices: [Device!]!
    hubs: [Hub!]!
    description: ProjectDescription!
}

union Project = TransferredProject | OngoingProject


type InstallerProjectCollection {
    installerProjects: [Project!]!
}

input ProjectCreateInput  {
    location: HomeLocationInput
    buildingType: HomeType
    constructionType: ConstructionType
    buildingYear: Int
    projectNumber: String
    sizeOfHousehold: Float
    buildingTitle: String!
    orderReferenceNumber: String!
}

input ProjectOnExistingHomeCreateInput {
    homeId: ID!
    installerId: ID!
    orderReferenceNumber: String!
    buildingTitle: String
    projectNumber: String!
}

input OrganizationProjectOnExistingHomeCreateInput {
    organizationId: ID!
    homeId: ID!
    orderReferenceNumber: String!
    buildingTitle: String
    projectNumber: String!
}

input ProjectUpdateInput {
    projectNumber: String
    orderReferenceNumber: String
    buildingTitle: String
}

input InstallerCreateOrganizationWithOwnerInput {
    organizationName: String!
    ownerEmail: String!
}

type ProjectCreatePayload {
    projectId: ID
    homeId: ID
    errors: [ProjectCreateError!]!
}

type ProjectOnExistingHomeCreatePayload   {
    projectId: ID
    errors: [ProjectCreateError!]!
}

type ProjectDeletePayload   {
    projectId: ID
    errors: [ProjectDeleteError!]!
}

type ProjectUpdatePayload {
    project: Project
    errors: [ProjectUpdateError!]!
}

type InstallerProjectUpdateStatusPayload {
    errors: [InstallerProjectUpdateStatusError!]!
}

type InstallerOrganizationAddInstallerPayload {
    errors: [InstallerOrganizationAddInstallerError!]!
}


type InstallerOrganizationRemoveInstallerPayload {
    errors: [InstallerOrganizationRemoveInstallerError!]!
}

type InstallerCreateOrganizationWithOwnerPayload  {
    organizationId: ID
    errors: [InstallerCreateOrganizationWithOwnerError!]!
}

type InstallerOrganizationCreateProjectPayload   {
    projectId: ID
    errors: [InstallerOrganizationCreateProjectError!]!
}

type InstallerOrganizationCreateProjectOnExistingHomePayload   {
    projectId: ID
    errors: [InstallerOrganizationCreateProjectOnExistingHomeError!]!
}

type ProjectAlreadyTransferredError  implements PayloadError {
    message: String!
    path: String!
}

type ClaimHomePayload {
    errors: [ClaimHomeError!]!
}

type ProjectDoesNotExistError implements PayloadError   {
    message: String!
    path: String!
}

type OrganizationDoesNotExistError implements PayloadError   {
    message: String!
    path: String!
}

type ProjectCreationFailedError implements PayloadError   {
    message: String!
    path: String!
}

type AlreadyOrganizationMemberError implements PayloadError {
    message: String!
    path: String!
}

type NotAuthorizedError implements PayloadError {
    message: String!
    path: String!
}

type OrganizationAlreadyExistsError implements PayloadError  {
    message: String!
    path: String!
}

type OwnerEmailAlreadyAssignedToAnOrganizationError implements PayloadError  {
    message: String!
    path: String!
}

type EmergencyContact   {
    id: ID!
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumber!
    isAlarmStationContact: Boolean
}

type EmergencyContactCollection   {
    emergencyContacts: [EmergencyContact!]!
}

input EmergencyContactAddInput {
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumberInput!
    language: String
}

input HomeMemberSetEmergencyNotificationsInput {
    enabled: Boolean!
}


input EmergencyContactUpdateInput {
    firstName: String
    lastName: String
}

input AlarmStationAddEmergencyContactInput {
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumberInput!
    fixedPriority: Int
}

input AlarmStationUpdateEmergencyContactInput {
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumberInput!
}

input UserSubscriptionInput {
    subscriptionType: SubscriptionType!
    tokens: Int!
}

input UpdateUserSubscriptionsInput {
    subscriptions: [UserSubscriptionInput!]!
}

input DeviceGroupCreateInput {
    name: String!
    deviceIds: [ID!]!
}

input DeviceGroupUpdateInput {
    name: String
    deviceIds: [ID!]
}

input ActivateGeofenceInput {
    radius: Int!
    referenceLat: Float!
    referenceLong: Float!
    type: GeofenceType!
}

input DeactivateGeofenceInput {
    type: GeofenceType!
}

input SetMOBCountdownInput {
    countdown: Int!
}

type DuplicatedEmergencyContactError implements PayloadError {
    message: String!
    path: String!
}

type HomeMemberToggleEmergencyNotificationsPayload {
    memberId: ID!
    errors: [HomeMemberToggleEmergencyNotificationsError!]!
}

type EmergencyContactAddPayload {
    emergencyContact: EmergencyContact
    errors: [EmergencyContactAddError!]!
}

type EmergencyContactDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

type EmergencyContactDeletePayload {
    id: ID
    errors: [EmergencyContactDeleteError!]!
}

type EmergencyContactUpdatePayload {
    emergencyContact: EmergencyContact
    errors: [EmergencyContactUpdateError!]!
}

enum AlarmStationStatus {
    ENABLED
    DISABLED
    SUBSCRIPTION_INACTIVE
}

enum SubscriptionType {
    ALARM_STATION
    CAR_CHARGING
    EMERGENCY_CONTACTS
    ENERGY_MANAGEMENT
    FIRE_ALARM
    HOMES
    HOUSING_ASSOCIATION
    INDOOR_CLIMATE_STATISTICS
    REMOTE_DEVICE_CONTROL
    SECURITY_ALARM
    SMART_ENERGY_ANALYSIS
    WATER_LEAK_ALARM
    NUMBER_OF_DEVICES_PER_TENANT
    NUMBER_OF_TENANTS
    NUMBER_OF_MEMBERS_PER_TENANT
    HOUSING_ASSOCIATION_ACCESS_CONTROL
}

type AlarmStationContact   {
    id: ID!
    firstName: String!
    lastName: String!
    phoneNumber: PhoneNumber!
}

type AlarmStationInfo   {
    homeId: ID!
    status: AlarmStationStatus!
    contacts: [AlarmStationContact!]!
}

type AlarmStationEnablePayload {
    errors: [AlarmStationEnableError!]!
}

type AlarmStationDisablePayload {
    errors: [AlarmStationDisableError!]!
}

type AlarmStationAddEmergencyContactPayload {
    errors: [AlarmStationAddEmergencyContactError!]!
}

type AlarmStationUpdateEmergencyContactPayload {
    errors: [AlarmStationUpdateEmergencyContactError!]!
}

type AlarmStationDeleteEmergencyContactPayload {
    errors: [AlarmStationRemoveEmergencyContactError!]!
}

type UpdateUserSubscriptionsPayload  {
    errors: [UpdateUserSubscriptionsError!]!
}

type DeviceGroupDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

type DeviceGroupEmptyDevicesError implements PayloadError {
    message: String!
    path: String!
}

type DeviceGroupDevicesRegisteredToDifferentHubsError implements PayloadError {
    message: String!
    path: String!
}


type SubjectDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

type InsuranceCompanyDoesNotExistError implements PayloadError {
    message: String!
    path: String!
}

type SubjectAlreadyInFavoritesError implements PayloadError {
    message: String!
    path: String!
}

type SubjectNotInFavoritesError implements PayloadError {
    message: String!
    path: String!
}

type FreezeProtectionInvalidThresholdTemperatureError implements PayloadError {
    message: String!
    path: String!
}

type DemandResponseAlreadyEnrolledError implements PayloadError {
    message: String!
    path: String!
}

type DemandResponseNotEnrolledError implements PayloadError {
    message: String!
    path: String!
}

type DemandResponseNotEligibleError implements PayloadError {
    message: String!
    path: String!
}

type SmartEnergyNotEnabledError implements PayloadError {
    message: String!
    path: String!
}

type RoutineDoesNotExistError implements PayloadError   {
    message: String!
    path: String!
}

type RoutineActionNotSupportedError implements PayloadError   {
    message: String!
    path: String!
}

type RoutineTriggerNotSupportedError implements PayloadError   {
    message: String!
    path: String!
}

type RoutineOriginInvalidError implements PayloadError   {
    message: String!
    path: String!
}

type RoutineDescriptionError implements PayloadError   {
    message: String!
    path: String!
}

type RoutineMustBeDeactivatedOrFinishedBeforeDeletionError implements PayloadError   {
    message: String!
    path: String!
}

type RoutineIsAlreadyActiveError implements PayloadError   {
    message: String!
    path: String!
}

type RoutineAlreadyInProcessOfActivationError implements PayloadError   {
    message: String!
    path: String!
}

type RoutineAlreadyInProcessOfDeactivationError implements PayloadError   {
    message: String!
    path: String!
}

type RoutineIsAlreadyInactiveError implements PayloadError   {
    message: String!
    path: String!
}

type RoutineMustBeInactiveError implements PayloadError   {
    message: String!
    path: String!
}

type DeviceGroupCreatePayload {
    deviceGroup: DeviceGroup
    errors: [DeviceGroupCreateError!]!
}

type DeviceGroupUpdatePayload {
    deviceGroup: DeviceGroup
    errors: [DeviceGroupUpdateError!]!
}

type DeviceGroupDeletePayload {
    errors: [DeviceGroupDeleteError!]!
}

type DeviceGroupTriggerCommandPayload {
    commandId: ID
    errors: [DeviceGroupTriggerCommandError!]!
}

type Favorite {
    isFavorite: Boolean!
    changedAt: String!
}

type FavoritesAddPayload {
    errors: [FavoritesAddError!]!
}

type FavoritesRemovePayload {
    errors: [FavoritesRemoveError!]!
}

enum GeofenceType {
  GEOFENCE
  ANCHOR
}

type GeofenceActivatePayload {
    isActive: Boolean!
    message: String,
    errors: [GeofenceActivateError!]!
}

type GeofenceDeactivatePayload {
    geofenceActivationStatus: Boolean!
    message: String,
    errors: [GeofenceDeactivateError!]!
}

type GeofenceStatus {
	isActive: Boolean!
	radius: Int!
	geofenceAlarm: String!
}

type GeofenceSendMOBEmergencyMessagePayload {
    success: Boolean!
}

type GeofenceSetMOBCountdownPayload {
    success: Boolean!
}

type GeofenceCancelMOBEmergencyPayload {
    success: Boolean!
}

union RoutineCreateError =
    HomeDoesNotExistError
    | RoutineActionNotSupportedError
    | RoutineTriggerNotSupportedError
    | RoutineOriginInvalidError
    | RoutineDescriptionError
union RoutineActivateError =
    RoutineDoesNotExistError
    | RoutineIsAlreadyActiveError
    | RoutineAlreadyInProcessOfActivationError
    | RoutineAlreadyInProcessOfDeactivationError
union RoutineDeactivateError =
    RoutineDoesNotExistError
    | RoutineAlreadyInProcessOfActivationError
    | RoutineAlreadyInProcessOfDeactivationError
    | RoutineIsAlreadyInactiveError

union RoutineDeleteError = RoutineDoesNotExistError | RoutineMustBeDeactivatedOrFinishedBeforeDeletionError
union RoutineUpdateDescriptionError = RoutineDoesNotExistError | RoutineDescriptionError
union RoutineUpdateError =
    | RoutineDoesNotExistError
    | RoutineMustBeInactiveError
    | RoutineActionNotSupportedError
    | RoutineTriggerNotSupportedError

union UpdatedPayload =
    DeviceUpdatePayload
    | DeviceUpdatedPayload
    | AreaUpdatedPayload
    | MemberUpdatedPayload
    | MemberInvitationUpdatedPayload
    | CloudConnectionUpdatedPayload
    | AlarmStationInfoUpdatePayload
    | DeviceGroupUpdatedPayload
    | FreezeProtectionUpdatedPayload
    | DemandResponseUpdatedPayload
    | RoutineUpdatedPayload
    | SmartEnergyUpdatedPayload
    | CollectiveAlarmUpdatedPayload

union UserUpdatedPayload =
    DemandResponseUpdatedPayload
    | AccountUpdatedPayload
union UserDeleteError = UserDoesNotExistError | DeletionFailedError
union AlarmResolveError = AlarmDoesNotExistError
union AlarmSetArmError =
    AlarmDoesNotExistError
    | AlarmOperationNotSupportedError
    | AlreadyArmedError
    | AlreadyDisarmedError
union AlarmAcknowledgeError = AlarmDoesNotExistError | AlarmOperationNotSupportedError
union AlarmAlertEmergencyContactsNotificationRequestError =
    AlarmDoesNotExistError
    | AlarmNotActiveError
    | AlarmAlertNotificationAlreadyRequestedError
    | AlarmAlertNotificationDismissedError
union AlarmAlertEmergencyContactsNotificationDismissError =
    AlarmDoesNotExistError
    | AlarmNotActiveError
union AlarmImOkEmergencyContactsNotificationRequestError =
    AlarmDoesNotExistError
    | AlarmAlertNotDeliveredError
    | AlarmActiveError
    | AlarmImOkNotificationAlreadyRequestedError
union AlarmImOkEmergencyContactsNotificationDismissError =
    AlarmDoesNotExistError
    | AlarmActiveError
union HomeCreateError = HomeAddressAlreadyExists | HomeInvalidUnitNumberError
union HomeUpdateError = HomeAddressAlreadyExists | HomeDoesNotExistError | HomeInvalidUnitNumberError
union HomeDeleteError = HomeDoesNotExistError
union HomeSetInsuranceInfoError = HomeDoesNotExistError | InsuranceCompanyDoesNotExistError
union AreaCreateError = HomeDoesNotExistError | AreaNameAlreadyExistsError
union AreaUpdateError = AreaDoesNotExistError | AreaNameAlreadyExistsError
union AreaDeleteError = AreaDoesNotExistError
union AreaAddDeviceError = AreaDoesNotExistError | DeviceDoesNotExistError
union AreaRemoveDeviceError = AreaDoesNotExistError | DeviceDoesNotExistError | DeviceNotInAreaError
union AreaAddHubError = AreaDoesNotExistError | HubDoesNotExistError
union AreaRemoveHubError = AreaDoesNotExistError | HubDoesNotExistError | HubNotInAreaError
union HubScanDevicesError = HomeDoesNotExistError | HubDoesNotExistError | HubNotRegisteredError | UnknownDeviceError | CommandNotSentError
union HubKeepDevicesError = HomeDoesNotExistError | HubDoesNotExistError | HubNotRegisteredError | CommandNotSentError | InvalidDeviceIdError | DeviceMaxCountPerHubExceededError
union HubRegisterError = HomeDoesNotExistError | HubDoesNotExistError | HubAlreadyRegisteredError | HubRegistrationFailedError
union HubRegisterDeviceWithQrError = UnknownQrCodeFormatError | UnknownDeviceError | HomeDoesNotExistError | HubDoesNotExistError | HubNotRegisteredError | DeviceAlreadyRegisteredError | DeviceMaxCountPerHubExceededError
union HubUnregisterError = HubDoesNotExistError | HubNotRegisteredError | HubUnregistrationFailedError
union HubUpdateNameError = HubDoesNotExistError
union HubCommandError = HubCommandExecutionError | HubDoesNotExistError
union HubResolveWaterGuardTamperModeError = HubDoesNotExistError | HubWaterGuardNotInTamperModeError | CommandNotSentError
union HubResolveWaterGuardTamperWarningNotificationError = HubDoesNotExistError | HubWaterGuardNotInTamperWarningModeError | HubWaterGuardTamperWarningModeNothingToResolveError
union HomeMemberInvitationError = UserAlreadyMemberInHome | HomeMemberWithGivenEmailAlreadyExists | InvalidFirstName | InvalidLastName | InvalidPhoneNumber | HomeMemberAlreadyInvitedError | HomeMemberInvitationMissingPhoneNumber | HomeDoesNotExistError
union HomeMemberUpdateInvitationError = InvitationDoesNotExistError | InvalidFirstName | InvalidLastName | InvalidPhoneNumber
union HomeMemberInvitationSendError = InvitationDoesNotExistError | HomeMemberInvitationMissingPhoneNumber
union HomeMemberDeleteError = HomeMemberDoesNotExistError | RemoveTheOwnerAttemptError
union HomeMemberUpdateError = HomeMemberDoesNotExistError | InvalidPhoneNumber | InvalidFirstName | InvalidLastName
union HomeMemberUpdateRoleError = RoleCouldNotBeChangedError | HomeMemberDoesNotExistError
union HomeMemberAcceptInvitationError = HomeDoesNotExistError | UserAlreadyMemberInHome | HomeMemberWithGivenEmailAlreadyExists | InvitationDoesNotExistError | InvitationTokenInvalidError | InvitationExpiredError | InvitationAlreadyAcceptedError | InvitationInactiveError
union HomeMemberRejectInvitationError = InvitationDoesNotExistError | InvitationAlreadyAcceptedError | InvitationTokenExpiredError  | InvitationTokenInvalidError | InvitationInactiveError
union HomeMemberRevokeInvitationError = InvitationDoesNotExistError | InvitationAlreadyAcceptedError | InvitationStillActiveError | InvitationInactiveError
union DeviceSetAccessPolicyForUserError = DeviceDoesNotExistError | UserDoesNotExistError
union UserMyAccountUpdateError = InvalidFirstName | InvalidLastName | InvalidPhoneNumber
union UserMyAccountUpdateLocaleError = LocaleNotSupported
union HubProvisioningRegistryUpdateError = HubDoesNotExistError
union HubProvisioningManufacturingUpdateError = HubDoesNotExistError
union HubProvisioningQrGenerationError = HubDoesNotExistError
union HubProvisioningError = HubProvisioningLimitExceededError
union HubProvisioningAcceptanceError = HubDoesNotExistError | HubRegistryNotCompleteError
union HubProvisioningDecomissionError = HubDoesNotExistError
union HubIdentifyError = InvalidSerialNumberFormatError | HubDoesNotExistError
union HubGetDppError = HubDoesNotExistError | HubInvalidHomeKitSetupPayloadError
union DeviceIdentifyError = InvalidSerialNumberFormatError | DeviceDoesNotExistError
union DeviceRegisterByQrCodeError =
    HomeDoesNotExistError
    | DeviceDoesNotExistError
    | DeviceAlreadyRegisteredError
    | UnknownQrCodeFormatError
union DeviceUnregisterError =
    DeviceDoesNotExistError
    | DeviceNotRegisteredError
    | CanNotUnregisterInternalDeviceError
    | InternalDeviceStillConnectedError
union DeviceToggleFavoriteError = DeviceDoesNotExistError
union DeviceSetRelayDeviceTypeError =
    DeviceDoesNotExistError
    | RelayConfigurationNotSupportedError
    | RelayEndDeviceTypeNotSupportedError
union DeviceSetIoModuleConfigurationError =
    DeviceDoesNotExistError
    | DeviceNotRegisteredError
    | IoModuleConfigurationNotSupportedError

union DeviceSetArmedError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union HubSetArmedError = HubDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union SetCollectiveAlarmForHomeHubsError = UnknownError
union DeviceSetBrightnessError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetColorError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetOnOffError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetOpenPercentError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetUnlockedError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetChildLockError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetTemperatureSetpointError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetTemperatureSetpointPercentageError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetTemperatureError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetTemperaturePercentageError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetClimateModeError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError | ClimateModeNotAvailableError
union DeviceSetMaximumFloorTemperatureError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetFrostGuardError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetNightSwitchError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceSetRegulatorModeError = DeviceDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union DeviceTriggerCommandError =
    DeviceDoesNotExistError
    | TraitNotSupportedForDeviceError
    | DeviceCommandInvalidInputError
union DeviceInvokeCommandError =
    DeviceDoesNotExistError
    | TraitNotSupportedForDeviceError
    | DeviceCommandInvalidInputError

union CommandRevertError = CommandDoesNotExistError

union HubSetGatewayConnectedError = HubDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union HubSetNetworkSsidError = HubDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError
union HubSetNetworkCredentialsError = HubDoesNotExistError | TraitNotSupportedForDeviceError | TraitUpdateFailedError

union DeviceUpdateNameError = DeviceDoesNotExistError
union UserMyAccountVerifyEmailError = UserDoesNotExistError | EmailAlreadyVerifiedError
union userMyAccountResendPostRegistrationPasswordResetEmailError = UserDoesNotExistError | EmailAlreadyVerifiedError
union UserInviteError = CampaignDoesNotExistError | InvalidFirstName | InvalidLastName | InvalidPhoneNumber | AlreadyInvitedError | MissingPhoneNumber | MissingEmailError
union UserAcceptInvitationError = InvitationDoesNotExistError | InvitationTokenInvalidError | InvitationExpiredError | InvitationAlreadyAcceptedError
union UserAccountSetRoleError = UserDoesNotExistError
union UserUpdatePreferencesError = UserDoesNotExistError
union UserUpdateNotificationPreferencesError = UserDoesNotExistError
union UpdateUserMarketingPreferencesError = UserDoesNotExistError

union ElhubConnectError = ElhubInvalidEnergyMeters | ElhubInvalidEnergyMeter | ElhubAlreadyConnected | ElhubMeterAlreadyRegistered | ElhubMeterRequiresAuthorization
union ElhubDisconnectError = ElhubNotConnected
union EnergyStatsSummaryError = DataNotAvailableError | MissingMeteringPointsError
union TimeSeriesError = InvalidRangeTimeSeriesError | InvalidGranularityTimeSeriesError | MissingParameterTimeSeriesError | TagNotUniqueTimeSeriesError | UnknownMarketBalanceAreaError | MissingMeteringPointsError | VATValueNotFoundError

union ClaimHomeError = HomeDoesNotExistError | ProjectAlreadyTransferredError
union ProjectCreateError = ProjectCreationFailedError | HomeInvalidUnitNumberError
union ProjectDeleteError = ProjectDoesNotExistError
union ProjectUpdateError = ProjectDoesNotExistError
union InstallerProjectUpdateStatusError = ProjectDoesNotExistError
union InstallerOrganizationAddInstallerError =
    OrganizationDoesNotExistError
    | UserDoesNotExistError
    | AlreadyOrganizationMemberError
    | NotAuthorizedError
union InstallerOrganizationRemoveInstallerError =
    OrganizationDoesNotExistError
    | UserDoesNotExistError
    | NotAuthorizedError
union InstallerCreateOrganizationWithOwnerError =
    OrganizationAlreadyExistsError
    | OwnerEmailAlreadyAssignedToAnOrganizationError
union InstallerOrganizationCreateProjectError =
    OrganizationDoesNotExistError
    | HomeInvalidUnitNumberError
    | ProjectCreationFailedError
union InstallerOrganizationCreateProjectOnExistingHomeError =
    OrganizationDoesNotExistError
    | ProjectCreationFailedError

union HomeMemberToggleEmergencyNotificationsError = HomeMemberDoesNotExistError
union EmergencyContactAddError = DuplicatedEmergencyContactError | InvalidFirstName | InvalidLastName | InvalidPhoneNumber | MissingPhoneNumber | LocaleNotSupported
union EmergencyContactDeleteError = EmergencyContactDoesNotExistError
union EmergencyContactUpdateError = EmergencyContactDoesNotExistError | InvalidFirstName | InvalidLastName

union PushNotificationEndpointSetError = UnableToSetPushNotificationEndpointError
union NotificationInboxMarkAsReadError = NotificationDoesNotExistError
union AlarmStationEnableError =
    SubscriptionInactiveError
    | AlarmStationAlreadyEnabledError
    | AlarmStationMissingHomeInfoError
    | AlarmStationMissingUserInfoError
    | AlarmStationCountryNotSupportedError
    | AlarmStationInvalidPostalCodeError
union AlarmStationDisableError =
    AlarmStationAlreadyDisabledError
    | AlarmStationActiveAlarmError
union AlarmStationAddEmergencyContactError =
    SubscriptionInactiveError
    | AlarmStationDisabledError
    | AlarmStationTooManyEmergencyContactsError
    | AlarmStationEmergencyContactAlreadyAddedError
union AlarmStationUpdateEmergencyContactError =
    AlarmStationDisabledError
    | AlarmStationEmergencyContactDoesNotExistError
union AlarmStationRemoveEmergencyContactError =
    AlarmStationDisabledError
    | AlarmStationEmergencyContactDoesNotExistError

union UpdateUserSubscriptionsError = UserDoesNotExistError


union DeviceGroupCreateError =
    DeviceDoesNotExistError
    | DeviceGroupEmptyDevicesError
    | HomeDoesNotExistError
    | DeviceGroupDevicesRegisteredToDifferentHubsError
union DeviceGroupUpdateError =
    DeviceGroupDoesNotExistError
    | DeviceGroupEmptyDevicesError
    | DeviceDoesNotExistError
union DeviceGroupDeleteError = DeviceGroupDoesNotExistError
union DeviceGroupTriggerCommandError =
    DeviceGroupDoesNotExistError
    | TraitNotSupportedError


union FavoritesAddError =
    SubjectDoesNotExistError
    | SubjectAlreadyInFavoritesError
union FavoritesRemoveError =
    SubjectDoesNotExistError
    | SubjectNotInFavoritesError

union FreezeProtectionConfigureError =
    HomeDoesNotExistError
    | FreezeProtectionInvalidThresholdTemperatureError
    | DeviceDoesNotExistError

union DemandResponseEnrollError =
    DemandResponseAlreadyEnrolledError
    | DemandResponseNotEligibleError
union DemandResponseUnenrollError =
    DemandResponseNotEnrolledError

union SmartEnergyEnableError =
    | HomeDoesNotExistError
union SmartEnergyDisableError =
    | SmartEnergyNotEnabledError
union SmartEnergySetHourlyLimitError =
    | SmartEnergyNotEnabledError
    | HomeDoesNotExistError
union SmartEnergyEnableDeviceError =
    | HomeDoesNotExistError
    | DeviceDoesNotExistError
    | SmartEnergyNotEnabledError
union SmartEnergyDisableDeviceError =
    | HomeDoesNotExistError
    | DeviceDoesNotExistError
    | SmartEnergyNotEnabledError

union HousingAssociationCollectiveAlarmCreateZoneError =
    | UnknownError

union HousingAssociationCollectiveAlarmDeleteZoneError =
    | CollectiveAlarmZoneDoesNotExistError

union HousingAssociationCollectiveAlarmConfigureZoneError =
    | CollectiveAlarmZoneDoesNotExistError

union HousingAssociationCollectiveAlarmZoneAddFacilityError =
    | CollectiveAlarmZoneDoesNotExistError

union HousingAssociationCollectiveAlarmZoneRemoveFacilityError =
    | CollectiveAlarmZoneDoesNotExistError

union HousingAssociationBuildingAddFacilityTempError =
    | UnknownError

union HousingAssociationBuildingRemoveFacilityTempError =
    | UnknownError

union CollectiveAlarmCreateError =
    | CollectiveAlarmAlreadyExistsError
union CollectiveAlarmDeleteError =
    | CollectiveAlarmDoesNotExistError
union CollectiveAlarmSetTenantsError =
    | CollectiveAlarmDoesNotExistError


union GeofenceActivateError = HomeDoesNotExistError | GeofenceAlreadyActivatedError
union GeofenceDeactivateError = HomeDoesNotExistError | GeofenceDoesNotExistError
