Skip to content

Commit

Permalink
Merge pull request #695 from OpenEVSE/jeremypoulter/issue29
Browse files Browse the repository at this point in the history
Certificate management
  • Loading branch information
jeremypoulter authored Aug 7, 2024
2 parents b594e58 + db87203 commit 7b83ecb
Show file tree
Hide file tree
Showing 41 changed files with 14,145 additions and 12,662 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
- wt32-eth01
- esp32-c3-devkitc-02
- elecrow_esp32_hmi
- elecrow_esp32_hmi_dev
# - elecrow_esp32_hmi_dev
- openevse_wifi_tft_v1
- openevse_wifi_tft_v1_dev

Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/build_gui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ jobs:
rm -f src/web_static/*.h
- name: Run PlatformIO
run:
run: |
pio run
git status
- name: Push any changed files
uses: stefanzweifel/git-auto-commit-action@v5
Expand Down
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,17 @@ lib/ESPAL
lib/MicroDebug
lib/StreamSpy
lib/MicroTasks
lib/jeremypoulter/ArduinoMongoose
lib/jeremypoulter/ConfigJson
lib/jeremypoulter/OpenEVSE
lib/jeremypoulter/ESPAL
lib/jeremypoulter/Micro Debug
lib/jeremypoulter/StreamSpy
lib/jeremypoulter/MicroTasks

*.bin
divert_sim/epoxyfsdata
divert_sim/epoxyeepromdata

*.pem
*.pem
111 changes: 110 additions & 1 deletion api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ paths:
$ref: ./models/Config.yaml
examples: {}
post:
description: |
Update the EVSE configuration
operationId: updateConfig
responses:
'200':
Expand Down Expand Up @@ -233,6 +235,8 @@ paths:
summary: Get the Manual Override status
description: Returns the current state of the manual override.
post:
description: |
Set the manual override
requestBody:
content:
application/json:
Expand Down Expand Up @@ -279,6 +283,9 @@ paths:
summary: Clear the manual override
/claims:
get:
description: |
List all claims made by EVSE clients.
The response will be an array of EVSE claims.
responses:
'200':
description: OK
Expand All @@ -294,6 +301,9 @@ paths:
summary: List EVSE claims
'/claims/{client}':
get:
description: |
Get the claim information for a specific client.
The response will be an EVSE claim.
responses:
'200':
description: OK
Expand Down Expand Up @@ -431,6 +441,9 @@ paths:
description: Numeric ID of the event
get:
summary: Get event details
description: |
This will get the details of a specific event in the schedule.
The response will be the EVSE state to set for that event.
responses:
'200':
description: OK
Expand All @@ -442,6 +455,8 @@ paths:
tags:
- Schedule
post:
description: |
Update the details of a specific event in the schedule.
responses:
'200':
$ref: '#/components/responses/UpdateSuccessful'
Expand All @@ -456,6 +471,8 @@ paths:
- Schedule
summary: Update event details
delete:
description: |
Remove a specific event from the schedule.
responses:
'200':
description: OK
Expand Down Expand Up @@ -523,7 +540,9 @@ paths:
'404':
$ref: '#/components/responses/NotFound'
operationId: getEventBlock
description: ''
description: |
Retrieve the log events for a specific block.
The block index range is returned by the /logs endpoint.
parameters:
- schema:
type: integer
Expand Down Expand Up @@ -817,6 +836,95 @@ paths:
$ref: '#/components/responses/BadRequest'
operationId: post-time
description: Set the time and associated config options. If not setting the time the `/config` endpoint can be used.
/certificates:
get:
summary: Get a list of certificates
description: |
Returns a list of certificates that have been uploaded to the OpenEVSE. The certificates are used to
authenticate the OpenEVSE to the MQTT broker, provide a secure web interface or as additional root CA
certificates.
operationId: listCertificates
tags:
- Certificates
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
certificates:
type: array
items:
$ref: './models/Certificate.yaml'
post:
summary: Upload a certificate
description: |
Upload a certificate to the OpenEVSE. The certificate can be used to authenticate the OpenEVSE to the MQTT
broker, provide a secure web interface or as additional root CA certificates.
operationId: uploadCertificate
tags:
- Certificates
requestBody:
content:
application/json:
schema:
$ref: './models/Certificate.yaml'
responses:
'200':
$ref: '#/components/responses/UpdateSuccessful'
'400':
$ref: '#/components/responses/BadRequest'
'/certificates/{id}':
get:
summary: Get a certificate
description: |
Returns a certificate that has been uploaded to the OpenEVSE. The certificate is used to
authenticate the OpenEVSE to the MQTT broker, provide a secure web interface or as additional root CA
certificates.
operationId: getCertificate
tags:
- Certificates
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: './models/Certificate.yaml'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
delete:
summary: Delete a certificate
description: |
Delete a certificate that has been uploaded to the OpenEVSE. The certificate is used to
authenticate the OpenEVSE to the MQTT broker, provide a secure web interface or as additional root CA
certificates.
operationId: deleteCertificate
tags:
- Certificates
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
'200':
$ref: '#/components/responses/UpdateSuccessful'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
components:
schemas:
Message:
Expand Down Expand Up @@ -963,3 +1071,4 @@ tags:
- name: Energy Meter
- name: Time
- name: Restart
- name: Certificates
68 changes: 50 additions & 18 deletions docs/mqtt.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### MQTT
# MQTT

MQTT and MQTTS (secure) connections are supported for status and control.

Expand All @@ -20,46 +20,45 @@ When the device disconnects from MQTT the same message is posted with `state":"d

All subsequent MQTT status updates will by default be be posted to `openevse-xxxx` where `xxxx` is the last 4 characters of the device ID. This base-topic can be changed via the MQTT service page.

#### OpenEVSE Status via MQTT
## OpenEVSE Status via MQTT

OpenEVSE can post its status values (e.g. amp, wh, temp1, temp2, temp3, pilot, status) to an MQTT server. Data will be published as a sub-topic of base topic, e.g `<base-topic>/amp`. Data is published to MQTT every 30s.

**The default `<base-topic>` is `openevse-xxxx` where `xxxx` is the last 4 characters of the device ID**

Claims & manual override are read accessible here:
`<base-topic>/override/` : get manual override ([json data], {"state": "null"} when there's no override)
`<base-topic>/override/set <json data> ` : set/update manual override ( data as refered from API : https://openevse.stoplight.io/docs/openevse-wifi-v4/e0ab0a4ad5e1e-set-the-manual-override )
`<base-topic>/override/` : get manual override ([json data], `{"state": "null"}` when there's no override)
`<base-topic>/override/set <json data>` : set/update manual override (data as refered from API : <https://openevse.stoplight.io/docs/openevse-wifi-v4/e0ab0a4ad5e1e-set-the-manual-override>)
`<base-topic>/override/set toggle` : toggle manual override
`<base-topic>/override/set clear` : clear manual override

`<base-topic>/claim/` : get mqtt service claim ([json data], {"state": "null"} when there's no claim )
`<base-topic>/claim/set <json data>` : set/update claim from MQTT service. Has same priority as HTTP service. ( data as refered from API : https://openevse.stoplight.io/docs/openevse-wifi-v4/ebc578ffa7ca7-make-update-an-evse-claim )
`<base-topic>/claim/` : get mqtt service claim ([json data], `{"state": "null"}` when there's no claim)
`<base-topic>/claim/set <json data>` : set/update claim from MQTT service. Has same priority as HTTP service. (data as refered from API : <https://openevse.stoplight.io/docs/openevse-wifi-v4/ebc578ffa7ca7-make-update-an-evse-claim>)
`<base-topic>/claim/set release` : release claim

Claim & override properties can be set independantly. Sending json with only some fields will update the current claim properties only.
Claim & override properties can be set independantly. Sending json with only some fields will update the current claim properties only.
To remove a selected claim/override property, just send "clear" as property parameter ( i.e. `<base-topic>/claim/set {"charge_current": "clear"}` )

Scheduler data:
`<base-topic>/schedule/` : get scheduler data ([json data]
`<base-topic>/schedule/set <json data>` : set/update schedules ( data as refered from API: https://openevse.stoplight.io/docs/openevse-wifi-v4/e87e6f3f90787-batch-update-schedule )
`<base-topic>/schedule/clear <id> :`remove related event
`<base-topic>/schedule/` : get scheduler data ([json data], `{"state": "null"}` when there's no shcedule)
`<base-topic>/schedule/set <json data>` : set/update schedules ( data as refered from API: <https://openevse.stoplight.io/docs/openevse-wifi-v4/e87e6f3f90787-batch-update-schedule>)
`<base-topic>/schedule/clear <id>` : remove related event

Limit:
`<base-topic>/limit/` : get limit data ([json data]
`<base-topic>/limit/set <json data>` : set/update limit ( data as refered from API:https://openevse.stoplight.io/docs/openevse-wifi-v4/c410fb5e48294-set-charge-limit )
`<base-topic>/limit/set clear` : clear current limit
`<base-topic>/limit/` : get limit data ([json data], `{"state": "null"}` when there's no limit)
`<base-topic>/limit/set <json data>` : set/update limit ( data as refered from API: <https://openevse.stoplight.io/docs/openevse-wifi-v4/c410fb5e48294-set-charge-limit>)
`<base-topic>/limit/set clear` : clear current limit

Main settings:

`<base-topic>/divertmode/set [1 | 2]` : enable (1)/ disable (2) divert mode
`<base-topic>/shaper/set [0 | 1]` : temporary enable (1)/ disable (0) current shaper ( doesn't survive reboot )
`<base-topic>/divertmode/set [1 | 2]` : enable (1)/ disable (2) divert mode
`<base-topic>/shaper/set [0 | 1]` : temporary enable (1)/ disable (0) current shaper ( doesn't survive reboot )
`<base-topic>/restart {"device": "gateway|evse"}` : restart the gateway or openevse module

Config:

`<base-topic>/config_version` : a volatile counter incremented for each config change
`<base-topic>/config` : expose the configuration as a json object

`<base-topic>/config_version` : a volatile counter incremented for each config change
`<base-topic>/config` : expose the configuration as a json object

MQTT setup is pre-populated with OpenEnergyMonitor [emonPi default MQTT server credentials](https://guide.openenergymonitor.org/technical/credentials/#mqtt).

Expand All @@ -69,3 +68,36 @@ MQTT setup is pre-populated with OpenEnergyMonitor [emonPi default MQTT server c
* After a few seconds `Connected: No` should change to `Connected: Yes` if connection is successful. Re-connection will be attempted every 10s. A refresh of the page may be needed.

*Note: `emon/xxxx` should be used as the base-topic if posting to emonPi MQTT server if you want the data to appear in emonPi Emoncms. See [emonPi MQTT docs](https://guide.openenergymonitor.org/technical/mqtt/).*

## Connecting to Cloud IoT services

### AWS IoT Core

Policy for AWS IoT Core:

```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:Connect",
"Resource": "arn:aws:iot:eu-west-2:489072314047:client/openevse-*"
},
{
"Effect": "Allow",
"Action": "iot:Subscribe",
"Resource": "arn:aws:iot:eu-west-2:489072314047:topicfilter/openevse/*"
},
{
"Effect": "Allow",
"Action": [
"iot:Receive",
"iot:Publish",
"iot:RetainPublish"
],
"Resource": "arn:aws:iot:eu-west-2:489072314047:topic/openevse/*"
}
]
}
```
21 changes: 21 additions & 0 deletions models/Certificate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
title: Certificate defenition
allOf:
- type: object
properties:
id:
type: string
description: 'The certificate ID, 64 bit hex number as a string'
name:
type: string
description: 'The human readable certificate name'
type:
type: string
description: 'The certificate type'
certificate:
type: string
description: 'A PEM formatted certificate'
private_key:
type: string
description: 'A PEM formatted private key'
x-tags:
- Certificates
3 changes: 3 additions & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ debug_flags =
#-D ENABLE_DEBUG_MICROTASKS
#-D ENABLE_DEBUG_ENERGY_METER
#-D ENABLE_DEBUG_MEMORY_MONITOR
#-D ENABLE_DEBUG_CETRIFICATES
#-D ENABLE_DEBUG_WEB_CETRIFICATES
#-D ENABLE_DEBUG_MONGOOSE_MQTT_CLIENT
src_build_flags =
# -D ARDUINOJSON_USE_LONG_LONG
# -D ENABLE_ASYNC_WIFI_SCAN
Expand Down
4 changes: 4 additions & 0 deletions src/app_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ String lang;
// Web server authentication (leave blank for none)
String www_username;
String www_password;
String www_certificate_id;

// Advanced settings
String esp_hostname;
Expand All @@ -66,6 +67,7 @@ uint32_t mqtt_port;
String mqtt_topic;
String mqtt_user;
String mqtt_pass;
String mqtt_certificate_id;
String mqtt_solar;
String mqtt_grid_ie;
String mqtt_vrms;
Expand Down Expand Up @@ -153,6 +155,7 @@ ConfigOpt *opts[] =
// Web server authentication (leave blank for none)
new ConfigOptDefinition<String>(www_username, "", "www_username", "au"),
new ConfigOptSecret(www_password, "", "www_password", "ap"),
new ConfigOptDefenition<String>(www_certificate_id, "", "www_certificate_id", "wc"),

// Advanced settings
new ConfigOptDefinition<String>(esp_hostname, esp_hostname_default, "hostname", "hn"),
Expand All @@ -177,6 +180,7 @@ ConfigOpt *opts[] =
new ConfigOptDefinition<String>(mqtt_topic, esp_hostname, "mqtt_topic", "mt"),
new ConfigOptDefinition<String>(mqtt_user, "emonpi", "mqtt_user", "mu"),
new ConfigOptSecret(mqtt_pass, "emonpimqtt2016", "mqtt_pass", "mp"),
new ConfigOptDefinition<String>(mqtt_certificate_id, "", "mqtt_certificate_id", "mct"),
new ConfigOptDefinition<String>(mqtt_solar, "", "mqtt_solar", "mo"),
new ConfigOptDefinition<String>(mqtt_grid_ie, "emon/emonpi/power1", "mqtt_grid_ie", "mg"),
new ConfigOptDefinition<String>(mqtt_vrms, "emon/emonpi/vrms", "mqtt_vrms", "mv"),
Expand Down
Loading

0 comments on commit 7b83ecb

Please sign in to comment.