Skip to content

Commit

Permalink
Add Smappee Infinity
Browse files Browse the repository at this point in the history
  • Loading branch information
anataty committed Jul 5, 2023
1 parent 1362318 commit 7ad0bcc
Show file tree
Hide file tree
Showing 7 changed files with 547 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .marketplace/devices/devices.yml
Original file line number Diff line number Diff line change
Expand Up @@ -608,3 +608,13 @@
blueprint_options:
- blueprint: gas_sensors/igd_toc_635
verification_level: verified

- id: smappee_infinity
display_name: Smappee Infinity
description: All-in-one energy management system.
icon: enapter-home
vendor: igd
category: power_meters
blueprint_options:
- blueprint: power_meters/smappee_infinity
verification_level: verified
Binary file added .marketplace/vendors/icons/smappee.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions .marketplace/vendors/vendors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,8 @@
display_name: International Gas Detectors Ltd
icon_url: https://raw.githubusercontent.com/Enapter/marketplace/main/.marketplace/vendors/icons/igd.png
website: https://www.internationalgasdetectors.com

- id: smappee
display_name: Smappee
icon_url: https://raw.githubusercontent.com/Enapter/marketplace/main/.marketplace/vendors/icons/smappee.png
website: https://www.smappee.com/
19 changes: 19 additions & 0 deletions power_meters/smappee_infinity/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Smappee Infinity

This [Enapter Device Blueprint](https://go.enapter.com/marketplace-readme) integrates **Smappee Infinity** - Smart energy management solution for any energy need - via [HTTP API](https://go.enapter.com/developers-enapter-http) implemented on [Enapter Virtual UCM](https://go.enapter.com/handbook-vucm).

## Connect to Enapter

- Sign up to Enapter Cloud using [Web](https://cloud.enapter.com/) or mobile app ([iOS](https://apps.apple.com/app/id1388329910), [Android](https://play.google.com/store/apps/details?id=com.enapter&hl=en)).
- Use [Enapter Gateway](https://go.enapter.com/handbook-gateway-setup) to run Virtual UCM.
- Create [Enapter Virtual UCM](https://go.enapter.com/handbook-vucm).
- [Upload](https://go.enapter.com/developers-upload-blueprint) this blueprint to Enapter Virtual UCM.
- Use the `Set Up Connection` command in the Enapter mobile or Web app to set up the Enel JuiceBox 32 communication parameters:
- [Your Client ID](https://go.enapter.com/smappee-devapi-docs);
- [Your Client secret](https://go.enapter.com/smappee-devapi-docs).
- [Your Smappee username](https://go.enapter.com/smappee-devapi-docs).
- [Your Smappee password](https://go.enapter.com/smappee-devapi-docs).

## References

- [Smappee Infinity product page](https://go.enapter.com/smappee-infinity-product)
200 changes: 200 additions & 0 deletions power_meters/smappee_infinity/manifest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
blueprint_spec: device/1.0
display_name: Smappee Infinity
description: Smart energy monitoring system
icon: enapter-home
vendor: smappee
license: MIT
author: enapter
contributors:
- anataty
support:
url: https://go.enapter.com/enapter-blueprint-support
email: [email protected]
verification_level: verified

communication_module:
product: ENP-VIRTUAL
lua:
dir: smappee_lua
amalg_mode: nodebug
dependencies:
- enapter-ucm

properties:
vendor:
type: string
display_name: Vendor
model:
type: string
display_name: Model

telemetry:
status:
type: string
display_name: State
enum:
- ok
- warning
consumption_power:
type: float
unit: Wh
display_name: Consumption
voltage1:
type: float
unit: V
display_name: Voltage Line 1
voltage2:
type: float
unit: V
display_name: Voltage Line 2
voltage3:
type: float
unit: V
display_name: Voltage Line 3
current1_PHASEA:
type: float
unit: A
display_name: Main Load Current phase A
current1_PHASEB:
type: float
unit: A
display_name: Main Load Current phase B
current1_PHASEC:
type: float
unit: A
display_name: Main Load Current phase C
active1_PHASEA:
type: float
unit: W
display_name: Main Load active power phase A
active1_PHASEB:
type: float
unit: W
display_name: Main Load active power phase B
active1_PHASEC:
type: float
unit: W
display_name: Main Load active power phase C
current2_PHASEA:
type: float
unit: A
display_name: Zone Carport/Cafe Current phase A
current2_PHASEB:
type: float
unit: A
display_name: Zone Carport/Cafe Current phase B
current2_PHASEC:
type: float
unit: A
display_name: Zone Carport/Cafe Current phase C
active2_PHASEA:
type: float
unit: W
display_name: Zone Carport/Cafe active power phase A
active2_PHASEB:
type: float
unit: W
display_name: Zone Carport/Cafe active power phase B
active2_PHASEC:
type: float
unit: W
display_name: Zone Carport/Cafe active power phase C
current3_PHASEA:
type: float
unit: A
display_name: Zone Hotel / Office Current phase A
current3_PHASEB:
type: float
unit: A
display_name: Zone Hotel / Office Current phase B
current3_PHASEC:
type: float
unit: A
display_name: Zone Hotel / Office Current phase C
active3_PHASEA:
type: float
unit: W
display_name: Zone Hotel / Office active power phase A
active3_PHASEB:
type: float
unit: W
display_name: Zone Hotel / Office active power phase B
active3_PHASEC:
type: float
unit: W
display_name: Zone Hotel / Office active power phase C

alerts:
no_data:
severity: warning
display_name: No data from device
description: >
Can't read data from Smappee Infinity.
Please check connection parameters.
connection_error:
severity: warning
display_name: Connection Error
description: >
Please use "Set Up Connection" command to set up your
Smappee account configuration.
no_service_location_name:
severity: warning
display_name: No service location name
description: >
Please use "Set Up Connection" command to set up your
Smappee service location name.
invalid_service_location_id:
severity: warning
display_name: Incorrect service location name
description: >
Please double check Smappee service location name.
command_groups:
connection:
display_name: Connection

commands:
# TODO: mark commands containing secrets
write_configuration:
display_name: Set Up Connection
description: Set your Smappee account parameters
group: connection
populate_values_command: read_configuration
ui:
icon: file-document-edit-outline
arguments:
username:
display_name: Smappee username
type: string
required: true
password:
display_name: Smappee password
type: string
required: true
client_id:
display_name: Smappee Client ID
type: string
required: true
client_secret:
display_name: Smappee Client Secret
type: string
required: true
service_location_name:
display_name: Smappee Service Location name
type: string
required: false
read_configuration:
display_name: Read Connection Parameters
group: connection
ui:
icon: file-check-outline

.cloud:
mobile_main_chart: consumption_power
mobile_charts:
- consumption_power
- active_power
- current
- voltage1
- voltage2
- voltage3
99 changes: 99 additions & 0 deletions power_meters/smappee_infinity/smappee_lua/main.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
local config = require('enapter.ucm.config')
local smappee = require('smappee')

-- Configuration variables must be also defined
-- in `write_configuration` command arguments in manifest.yml
USERNAME = 'username'
PASSWORD = 'password'
CLIENT_SECRET = 'client_secret'
CLIENT_ID = 'client_id'
SERVICE_LOCATION_NAME = 'service_location_name'

-- Initiate device firmware. Called at the end of the file.
function main()
scheduler.add(30000, send_properties)
scheduler.add(2000, send_telemetry)

config.init({
[USERNAME] = { type = 'string', required = true },
[PASSWORD] = { type = 'string', required = true },
[CLIENT_SECRET] = { type = 'string', required = true },
[CLIENT_ID] = { type = 'string', required = true },
[SERVICE_LOCATION_NAME] = { type = 'string', required = false },
})
end

function send_properties()
enapter.send_properties({
vendor = 'Smappee',
model = 'Infinity',
})
end

function send_telemetry()
local conn, err = connect_smappee()
if err then
enapter.log("Can't connect to Smappee: " .. err)
enapter.send_telemetry({
status = 'warning',
alerts = { 'connection_error' },
})
return
else
local location_name = config.read(SERVICE_LOCATION_NAME)
if tostring(location_name) ~= '' then
conn:set_service_location_id(location_name, conn:get_service_locations())

local telemetry = conn:get_electricity_consumption((os.time() - 600) * 1000, os.time() * 1000)
if next(telemetry) then
if telemetry['consumption_power'] then
telemetry['status'] = 'ok'
telemetry['alerts'] = {}
enapter.send_telemetry(telemetry)
else
telemetry['status'] = 'warning'
enapter.send_telemetry(telemetry)
end
else
enapter.send_telemetry({ status = 'warning', alerts = { 'no_data' } })
end
else
enapter.send_telemetry({ status = 'warning', alerts = { 'no_service_location_name' } })
end
end
end

-- holds global Smappee connection
local conn

function connect_smappee()
if conn and conn.expires ~= nil then
if conn.expires <= os.time() then
conn.access_token, conn.new_token, conn.expires = conn:refresh_token()
end

return conn, nil
end

local values, err = config.read_all()
if err then
enapter.log('cannot read config: ' .. tostring(err), 'error')
return nil, 'cannot_read_config'
else
local client_secret, client_id = values[CLIENT_SECRET], values[CLIENT_ID]
local username, password = values[USERNAME], values[PASSWORD]

if not client_secret or not client_id or not username or not password then
return nil, 'not_configured'
else
conn = smappee.new(username, password, client_secret, client_id)
if conn ~= nil then
return conn, nil
else
return nil, 'no_connection'
end
end
end
end

main()

0 comments on commit 7ad0bcc

Please sign in to comment.