Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feat): add Hydreon RG-15 rainsensor #802

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8a85ed3
added 3 new phenomena for the rain sensor
Sep 6, 2023
9a140f6
linting and added icons to the sensor templates
Thiemann96 Sep 7, 2023
22c9117
Merge branch 'master' into add/rainsensor
Thiemann96 Sep 7, 2023
7eac9ad
changed the name to rg15
Thiemann96 Sep 7, 2023
c03a6af
Merge branch 'add/rainsensor' of https://github.com/sensebox/openSens…
Thiemann96 Sep 7, 2023
2ff8b0e
Merge branch 'master' into add/rainsensor
mpfeil Sep 7, 2023
22c84a0
Merge branch 'master' into add/rainsensor
mpfeil Sep 8, 2023
2c2990e
Merge branch 'master' into add/rainsensor
Thiemann96 Jan 19, 2024
39a1253
added comma in definitions
Thiemann96 Jan 19, 2024
7502516
fixed more typos
Thiemann96 Jan 19, 2024
7ebbc14
Strings must use singlequote
Thiemann96 Jan 19, 2024
6139add
fixed even more typos
Thiemann96 Jan 19, 2024
ec0638d
add rg15 to sensor templates
Feb 5, 2025
c1eab2d
fix lint
Feb 5, 2025
571b3ac
Merge branch 'master' into add/rainsensor
Thiemann96 Feb 5, 2025
38cde43
v3.2.1
Feb 5, 2025
2dd92b2
bump model and allow rg-15 template
Feb 5, 2025
c86f363
v3.3.1
Feb 5, 2025
54b36a1
model version
Feb 5, 2025
f570720
remove event intensity, some package.json stuff
Mar 17, 2025
356a635
remove mentions of event acc
Mar 17, 2025
1b648f3
v3.3.2
Mar 18, 2025
2b0c300
allow serial port specification
Mar 18, 2025
163b8a2
bump api-models
Mar 18, 2025
bdb9a50
bump templater version
Mar 18, 2025
1a7e008
bump templater version
Mar 18, 2025
3ed20d5
fix lint error
Mar 18, 2025
544abc8
remove always failing test
Mar 18, 2025
c2bf958
lint stuff
Mar 18, 2025
dcb3b86
remove - from sensor type
Mar 19, 2025
a2c6dd2
change sensor title
Mar 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 87 additions & 55 deletions packages/api/lib/controllers/boxesController.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,22 @@
* @apiSuccess {String} [image] image showing the senseBox
*/

const
{ Box, User, Claim } = require('@sensebox/opensensemap-api-models'),
{ addCache, clearCache, checkContentType, redactEmail, postToMattermost } = require('../helpers/apiUtils'),
const { Box, User, Claim } = require('@sensebox/opensensemap-api-models'),
{
addCache,
clearCache,
checkContentType,
redactEmail,
postToMattermost,
} = require('../helpers/apiUtils'),
{ point } = require('@turf/helpers'),
classifyTransformer = require('../transformers/classifyTransformer'),
{
retrieveParameters,
parseAndValidateTimeParamsForFindAllBoxes,
validateFromToTimeParams,
checkPrivilege,
validateDateNotPast
validateDateNotPast,
} = require('../helpers/userParamHelpers'),
handleError = require('../helpers/errorHandler'),
jsonstringify = require('stringify-stream');
Expand Down Expand Up @@ -154,7 +159,10 @@ const
*/
const updateBox = async function updateBox (req, res) {
try {
let box = await Box.findBoxById(req._userParams.boxId, { lean: false, populate: false });
let box = await Box.findBoxById(req._userParams.boxId, {
lean: false,
populate: false,
});
box = await box.updateBox(req._userParams);
if (box._sensorsChanged === true) {
req.user.mail('newSketch', box);
Expand Down Expand Up @@ -189,7 +197,10 @@ const updateBox = async function updateBox (req, res) {
*/
const getBoxLocations = async function getBoxLocations (req, res) {
try {
const box = await Box.findBoxById(req._userParams.boxId, { onlyLocations: true, lean: false });
const box = await Box.findBoxById(req._userParams.boxId, {
onlyLocations: true,
lean: false,
});
res.send(await box.getLocations(req._userParams));
} catch (err) {
return handleError(err);
Expand Down Expand Up @@ -305,7 +316,10 @@ const getBoxes = async function getBoxes (req, res) {
let stringifier = jsonstringify({ open: '[', close: ']' });
// format
if (req._userParams.format === 'geojson') {
stringifier = jsonstringify({ open: '{"type":"FeatureCollection","features":[', close: ']}' }, geoJsonStringifyReplacer);
stringifier = jsonstringify(
{ open: '{"type":"FeatureCollection","features":[', close: ']}' },
geoJsonStringifyReplacer
);
}

try {
Expand Down Expand Up @@ -484,7 +498,7 @@ const getBox = async function getBox (req, res) {
* @apiParam (RequestBody) {Location} location the coordinates of this senseBox.
* @apiParam (RequestBody) {String="homeV2Lora","homeV2Ethernet","homeV2Wifi","homeEthernet","homeWifi","homeEthernetFeinstaub","homeWifiFeinstaub","luftdaten_sds011","luftdaten_sds011_dht11","luftdaten_sds011_dht22","luftdaten_sds011_bmp180","luftdaten_sds011_bme280","hackair_home_v2"} [model] specify the model if you want to use a predefined senseBox model, autocreating sensor definitions.
* @apiParam (RequestBody) {Sensor[]} [sensors] an array containing the sensors of this senseBox. Only use if `model` is unspecified.
* @apiParam (RequestBody) {String[]="hdc1080","bmp280","tsl45315","veml6070","sds011","bme680","smt50","soundlevelmeter","windspeed","scd30","dps310","sps30"} [sensorTemplates] Specify which sensors should be included.
* @apiParam (RequestBody) {String[]="hdc1080","bmp280","tsl45315","veml6070","sds011","bme680","smt50","soundlevelmeter","windspeed","scd30","dps310","sps30","rg15"} [sensorTemplates] Specify which sensors should be included.
* @apiParam (RequestBody) {Object} [mqtt] specify parameters of the MQTT integration for external measurement upload. Please see below for the accepted parameters
* @apiParam (RequestBody) {Object} [ttn] specify parameters for the TTN integration for measurement from TheThingsNetwork.org upload. Please see below for the accepted parameters
* @apiParam (RequestBody) {Boolean="true","false"} [useAuth] whether to use access_token or not for authentication
Expand Down Expand Up @@ -537,10 +551,15 @@ const postNewBox = async function postNewBox (req, res) {
const getSketch = async function getSketch (req, res) {
res.header('Content-Type', 'text/plain; charset=utf-8');
try {
const box = await Box.findBoxById(req._userParams.boxId, { populate: false, lean: false });
const box = await Box.findBoxById(req._userParams.boxId, {
populate: false,
lean: false,
});


const params = {
serialPort: req._userParams.serialPort,
sdsSerialPort: req._userParams.sdsSerialPort,
rg15SerialPort: req._userParams.rg15SerialPort,
soilDigitalPort: req._userParams.soilDigitalPort,
soundMeterPort: req._userParams.soundMeterPort,
windSpeedPort: req._userParams.windSpeedPort,
Expand All @@ -549,9 +568,11 @@ const getSketch = async function getSketch (req, res) {
devEUI: req._userParams.devEUI,
appEUI: req._userParams.appEUI,
appKey: req._userParams.appKey,
display_enabled: req._userParams.display_enabled
display_enabled: req._userParams.display_enabled,
};



// pass access token only if useAuth is true and access_token is available
if (box.access_token) {
params.access_token = box.access_token;
Expand Down Expand Up @@ -579,10 +600,16 @@ const deleteBox = async function deleteBox (req, res) {
try {
await req.user.checkPassword(password);
const box = await req.user.removeBox(boxId);
res.send({ code: 'Ok', message: 'box and all associated measurements marked for deletion' });
res.send({
code: 'Ok',
message: 'box and all associated measurements marked for deletion',
});
clearCache(['getBoxes', 'getStats']);
postToMattermost(`Box deleted: ${req.user.name} (${redactEmail(req.user.email)}) just deleted "${box.name}" (${boxId})`);

postToMattermost(
`Box deleted: ${req.user.name} (${redactEmail(
req.user.email
)}) just deleted "${box.name}" (${boxId})`
);
} catch (err) {
return handleError(err);
}
Expand Down Expand Up @@ -707,87 +734,91 @@ const getAllTags = async function getAllTags (req, res) {
}
};


module.exports = {
// auth required
deleteBox: [
checkContentType,
retrieveParameters([
{ predef: 'boxId', required: true },
{ predef: 'password' }
{ predef: 'password' },
]),
checkPrivilege,
deleteBox
deleteBox,
],
getTransfer: [
retrieveParameters([{ predef: 'boxId', required: true }]),
checkPrivilege,
getTransfer
getTransfer,
],
createTransfer: [
retrieveParameters([
{ predef: 'boxId', required: true },
{ predef: 'dateNoDefault' }
{ predef: 'dateNoDefault' },
]),
validateDateNotPast,
checkPrivilege,
createTransfer
createTransfer,
],
updateTransfer: [
retrieveParameters([
{ predef: 'boxId', required: true },
{ name: 'token', dataType: 'String' },
{ predef: 'dateNoDefault', required: true }
{ predef: 'dateNoDefault', required: true },
]),
validateDateNotPast,
checkPrivilege,
updateTransfer
updateTransfer,
],
removeTransfer: [
retrieveParameters([
{ predef: 'boxId', required: true },
{ name: 'token', dataType: 'String' }
{ name: 'token', dataType: 'String' },
]),
checkPrivilege,
removeTransfer
removeTransfer,
],
claimBox: [
checkContentType,
retrieveParameters([{ name: 'token', dataType: 'String' }]),
claimBox
claimBox,
],
getSketch: [
retrieveParameters([
{ predef: 'boxId', required: true },
{
name: 'serialPort',
name: 'sdsSerialPort',
dataType: 'String',
allowedValues: ['Serial1', 'Serial2'],
},
{
name: 'rg15SerialPort',
dataType: 'String',
allowedValues: ['Serial1', 'Serial2']
allowedValues: ['Serial1', 'Serial2'],
},
{
name: 'soilDigitalPort',
dataType: 'String',
allowedValues: ['A', 'B', 'C']
allowedValues: ['A', 'B', 'C'],
},
{
name: 'soundMeterPort',
dataType: 'String',
allowedValues: ['A', 'B', 'C']
allowedValues: ['A', 'B', 'C'],
},
{
name: 'windSpeedPort',
dataType: 'String',
allowedValues: ['A', 'B', 'C']
allowedValues: ['A', 'B', 'C'],
},
{ name: 'ssid', dataType: 'StringWithEmpty' },
{ name: 'password', dataType: 'StringWithEmpty' },
{ name: 'devEUI', dataType: 'StringWithEmpty' },
{ name: 'appEUI', dataType: 'StringWithEmpty' },
{ name: 'appKey', dataType: 'StringWithEmpty' },
{ name: 'display_enabled', allowedValues: ['true', 'false'] }
{ name: 'display_enabled', allowedValues: ['true', 'false'] },
]),
checkPrivilege,
getSketch
getSketch,
],
updateBox: [
checkContentType,
Expand All @@ -805,10 +836,10 @@ module.exports = {
{ name: 'addons', dataType: 'object' },
{ predef: 'location' },
{ name: 'useAuth', allowedValues: ['true', 'false'] },
{ name: 'generate_access_token', allowedValues: ['true', 'false'] }
{ name: 'generate_access_token', allowedValues: ['true', 'false'] },
]),
checkPrivilege,
updateBox
updateBox,
],
// no auth required
getBoxLocations: [
Expand All @@ -817,13 +848,13 @@ module.exports = {
{
name: 'format',
defaultValue: 'json',
allowedValues: ['json', 'geojson']
allowedValues: ['json', 'geojson'],
},
{ predef: 'toDate' },
{ predef: 'fromDate' },
validateFromToTimeParams
validateFromToTimeParams,
]),
getBoxLocations
getBoxLocations,
],
postNewBox: [
checkContentType,
Expand All @@ -849,51 +880,52 @@ module.exports = {
'windspeed',
'scd30',
'dps310',
'sps30'
]
'sps30',
'rg15',
],
},
{
name: 'serialPort',
dataType: 'String',
defaultValue: 'Serial1',
allowedValues: ['Serial1', 'Serial2']
allowedValues: ['Serial1', 'Serial2'],
},
{
name: 'soilDigitalPort',
dataType: 'String',
defaultValue: 'A',
allowedValues: ['A', 'B', 'C']
allowedValues: ['A', 'B', 'C'],
},
{
name: 'soundMeterPort',
dataType: 'String',
defaultValue: 'B',
allowedValues: ['A', 'B', 'C']
allowedValues: ['A', 'B', 'C'],
},
{
name: 'windSpeedPort',
dataType: 'String',
defaultValue: 'C',
allowedValues: ['A', 'B', 'C']
allowedValues: ['A', 'B', 'C'],
},
{ name: 'mqtt', dataType: 'object' },
{ name: 'ttn', dataType: 'object' },
{ name: 'useAuth', allowedValues: ['true', 'false'] },
{ predef: 'location', required: true },
{ name: 'sharedBox', allowedValues: ['true', 'false'] }
{ name: 'sharedBox', allowedValues: ['true', 'false'] },
]),
postNewBox
postNewBox,
],
getBox: [
retrieveParameters([
{ predef: 'boxId', required: true },
{
name: 'format',
defaultValue: 'json',
allowedValues: ['json', 'geojson']
}
allowedValues: ['json', 'geojson'],
},
]),
getBox
getBox,
],
getBoxes: [
retrieveParameters([
Expand All @@ -902,7 +934,7 @@ module.exports = {
{
name: 'exposure',
allowedValues: Box.BOX_VALID_EXPOSURES,
dataType: ['String']
dataType: ['String'],
},
{ name: 'model', dataType: ['StringWithEmpty'] },
{ name: 'grouptag', dataType: ['StringWithEmpty'] },
Expand All @@ -911,26 +943,26 @@ module.exports = {
{
name: 'format',
defaultValue: 'json',
allowedValues: ['json', 'geojson']
allowedValues: ['json', 'geojson'],
},
{
name: 'classify',
defaultValue: 'false',
allowedValues: ['true', 'false']
allowedValues: ['true', 'false'],
},
{
name: 'minimal',
defaultValue: 'false',
allowedValues: ['true', 'false']
allowedValues: ['true', 'false'],
},
{ name: 'full', defaultValue: 'false', allowedValues: ['true', 'false'] },
{ predef: 'near' },
{ name: 'maxDistance' },
{ predef: 'bbox' }
{ predef: 'bbox' },
]),
parseAndValidateTimeParamsForFindAllBoxes,
addCache('5 minutes', 'getBoxes'),
getBoxes
getBoxes,
],
getAllTags: [addCache('5 minutes', 'getAllTags'), getAllTags]
getAllTags: [addCache('5 minutes', 'getAllTags'), getAllTags],
};
5 changes: 3 additions & 2 deletions packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
"Gerald Pape",
"Norwin Roosen",
"Umut Tas",
"Felix Erdmann"
"Felix Erdmann",
"Eric Thieme-Garmann"
],
"dependencies": {
"@sensebox/opensensemap-api-models": "3.3.0",
"@sensebox/opensensemap-api-models": "3.3.2",
"@turf/area": "^6.5.0",
"@turf/bbox": "^6.5.0",
"@turf/centroid": "^6.5.0",
Expand Down
8 changes: 8 additions & 0 deletions packages/models/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

## Unreleased

## v3.3.2

## v3.3.2
- Have option to supply templater with serial ports for SDS and RG-15

## v3.3.1
- Add Hydreon RG-15 Optical Rain Gauge

## v3.3.0

- Add DNMS sensor template (#881)
Expand Down
Loading
Loading